| Index: chrome/browser/navigation_controller.h
|
| ===================================================================
|
| --- chrome/browser/navigation_controller.h (revision 1840)
|
| +++ chrome/browser/navigation_controller.h (working copy)
|
| @@ -5,7 +5,7 @@
|
| #ifndef CHROME_BROWSER_NAVIGATION_CONTROLLER_H_
|
| #define CHROME_BROWSER_NAVIGATION_CONTROLLER_H_
|
|
|
| -#include <hash_map>
|
| +#include <map>
|
|
|
| #include "base/linked_ptr.h"
|
| #include "base/ref_counted.h"
|
| @@ -21,24 +21,17 @@
|
| class WebContents;
|
| class TabContentsCollector;
|
| struct TabNavigation;
|
| +struct ViewHostMsg_FrameNavigate_Params;
|
|
|
| -namespace printing {
|
| -class PrintViewManager;
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| +// A NavigationController maintains the back-forward list for a single tab and
|
| +// manages all navigation within that list.
|
| //
|
| -// NavigationController class
|
| -//
|
| -// A NavigationController maintains navigation data. We have one
|
| -// NavigationController instance per tab.
|
| -//
|
| // The NavigationController also owns all TabContents for the tab. This is to
|
| // make sure that we have at most one TabContents instance per type.
|
| -//
|
| -////////////////////////////////////////////////////////////////////////////////
|
| class NavigationController {
|
| public:
|
| + // Notification details ------------------------------------------------------
|
| +
|
| // Provides the details for a NOTIFY_NAV_ENTRY_CHANGED notification.
|
| struct EntryChangedDetails {
|
| // The changed navigation entry after it has been updated.
|
| @@ -48,6 +41,7 @@
|
| int index;
|
| };
|
|
|
| + // Provides the details for a NOTIFY_NAV_ENTRY_COMMITTED notification.
|
| struct LoadCommittedDetails {
|
| // By default, the entry will be filled according to a new main frame
|
| // navigation.
|
| @@ -88,7 +82,10 @@
|
| }
|
| };
|
|
|
| + // ---------------------------------------------------------------------------
|
| +
|
| NavigationController(TabContents* initial_contents, Profile* profile);
|
| +
|
| // Creates a NavigationController from the specified history. Processing
|
| // for this is asynchronous and handled via the RestoreHelper (in
|
| // navigation_controller.cc).
|
| @@ -99,9 +96,25 @@
|
| HWND parent);
|
| ~NavigationController();
|
|
|
| - // Same as Reload, but doesn't check if current entry has POST data.
|
| - void ReloadDontCheckForRepost();
|
| + // Begin the destruction sequence for this NavigationController and all its
|
| + // registered tabs. The sequence is as follows:
|
| + // 1. All tabs are asked to Destroy themselves.
|
| + // 2. When each tab is finished Destroying, it will notify the controller.
|
| + // 3. Once all tabs are Destroyed, the NavigationController deletes itself.
|
| + // This ensures that all the TabContents outlive the NavigationController.
|
| + void Destroy();
|
|
|
| + // Clone the receiving navigation controller. Only the active tab contents is
|
| + // duplicated. It is created as a child of the provided HWND.
|
| + NavigationController* Clone(HWND hwnd);
|
| +
|
| + // Returns the profile for this controller. It can never be NULL.
|
| + Profile* profile() const {
|
| + return profile_;
|
| + }
|
| +
|
| + // Active entry --------------------------------------------------------------
|
| +
|
| // Returns the active entry, which is the pending entry if a navigation is in
|
| // progress or the last committed entry otherwise. NOTE: This can be NULL!!
|
| //
|
| @@ -115,19 +128,7 @@
|
| // it is the pending_entry_index_.
|
| int GetCurrentEntryIndex() const;
|
|
|
| - // Returns the pending entry corresponding to the navigation that is
|
| - // currently in progress, or null if there is none.
|
| - NavigationEntry* GetPendingEntry() const {
|
| - return pending_entry_;
|
| - }
|
| -
|
| - // Returns the index of the pending entry or -1 if the pending entry
|
| - // corresponds to a new navigation (created via LoadURL).
|
| - int GetPendingEntryIndex() const {
|
| - return pending_entry_index_;
|
| - }
|
| -
|
| - // Returns the last committed entry, which may be null if there are no
|
| + // Returns the last committed entry, which may be null if there are no
|
| // committed entries.
|
| NavigationEntry* GetLastCommittedEntry() const;
|
|
|
| @@ -136,6 +137,8 @@
|
| return last_committed_entry_index_;
|
| }
|
|
|
| + // Navigation list -----------------------------------------------------------
|
| +
|
| // Returns the number of entries in the NavigationControllerBase, excluding
|
| // the pending entry if there is one.
|
| int GetEntryCount() const {
|
| @@ -150,86 +153,156 @@
|
| // if out of bounds.
|
| NavigationEntry* GetEntryAtOffset(int offset) const;
|
|
|
| - bool CanStop() const;
|
| + // Returns the index of the specified entry, or -1 if entry is not contained
|
| + // in this NavigationControllerBase.
|
| + int GetIndexOfEntry(const NavigationEntry* entry) const;
|
|
|
| - // Return whether this controller can go back.
|
| + // Return the index of the entry with the corresponding type, instance, and
|
| + // page_id, or -1 if not found. Use a NULL instance if the type is not
|
| + // TAB_CONTENTS_WEB.
|
| + int GetEntryIndexWithPageID(TabContentsType type,
|
| + SiteInstance* instance,
|
| + int32 page_id) const;
|
| +
|
| + // Return the entry with the corresponding type, instance, and page_id, or
|
| + // NULL if not found. Use a NULL instance if the type is not
|
| + // TAB_CONTENTS_WEB.
|
| + NavigationEntry* GetEntryWithPageID(TabContentsType type,
|
| + SiteInstance* instance,
|
| + int32 page_id) const;
|
| +
|
| + // Pending entry -------------------------------------------------------------
|
| +
|
| + // Commits the current pending entry and issues the NOTIFY_NAV_ENTRY_COMMIT
|
| + // notification. No changes are made to the entry during this process, it is
|
| + // just moved from pending to committed. This is an alternative to
|
| + // RendererDidNavigate for simple TabContents types.
|
| + //
|
| + // When the pending entry is a new navigation, it will have a page ID of -1.
|
| + // The caller should leave this as-is. CommitPendingEntry will generate a
|
| + // new page ID for you and update the TabContents with that ID.
|
| + void CommitPendingEntry();
|
| +
|
| + // Calling this may cause the active tab contents to switch if the current
|
| + // entry corresponds to a different tab contents type.
|
| + void DiscardPendingEntry();
|
| +
|
| + // Returns the pending entry corresponding to the navigation that is
|
| + // currently in progress, or null if there is none.
|
| + NavigationEntry* GetPendingEntry() const {
|
| + return pending_entry_;
|
| + }
|
| +
|
| + // Returns the index of the pending entry or -1 if the pending entry
|
| + // corresponds to a new navigation (created via LoadURL).
|
| + int GetPendingEntryIndex() const {
|
| + return pending_entry_index_;
|
| + }
|
| +
|
| + // New navigations -----------------------------------------------------------
|
| +
|
| + // Loads the specified URL.
|
| + void LoadURL(const GURL& url, PageTransition::Type type);
|
| +
|
| + // Load the specified URL the next time it becomes active.
|
| + void LoadURLLazily(const GURL& url, PageTransition::Type type,
|
| + const std::wstring& title, SkBitmap* icon);
|
| +
|
| + // Loads the current page if this NavigationController was restored from
|
| + // history and the current page has not loaded yet.
|
| + void LoadIfNecessary();
|
| +
|
| + // Renavigation --------------------------------------------------------------
|
| +
|
| + // Navigation relative to the "current entry"
|
| bool CanGoBack() const;
|
| -
|
| - // Return whether this controller can go forward.
|
| bool CanGoForward() const;
|
| -
|
| - // Causes the controller to go back.
|
| void GoBack();
|
| -
|
| - // Causes the controller to go forward.
|
| void GoForward();
|
|
|
| - // Causes the controller to go to the specified index.
|
| + // Navigates to the specified absolute index.
|
| void GoToIndex(int index);
|
|
|
| - // Causes the controller to go to the specified offset from current. Does
|
| - // nothing if out of bounds.
|
| + // Navigates to the specified offset from the "current entry". Does nothing if
|
| + // the offset is out of bounds.
|
| void GoToOffset(int offset);
|
|
|
| - // Causes the controller to stop a pending navigation if any.
|
| - void Stop();
|
| -
|
| - // Causes the controller to reload the current entry. Will prompt the user if
|
| - // reloading a URL with POST data and the active WebContents isn't showing the
|
| - // POST interstitial page.
|
| + // Reloads the current entry. The user will be prompted if the URL has POST
|
| + // data and the active WebContents isn't showing the POST interstitial page.
|
| void Reload();
|
|
|
| - // Return the entry with the corresponding type, instance, and page_id, or
|
| - // NULL if not found. Use a NULL instance if the type is not
|
| - // TAB_CONTENTS_WEB.
|
| - NavigationEntry* GetEntryWithPageID(TabContentsType type,
|
| - SiteInstance* instance,
|
| - int32 page_id) const;
|
| + // Same as Reload, but doesn't check if current entry has POST data.
|
| + void ReloadDontCheckForRepost();
|
|
|
| - // Causes the controller to load the specified entry. The controller
|
| - // assumes ownership of the entry.
|
| - // NOTE: Do not pass an entry that the controller already owns!
|
| - void LoadEntry(NavigationEntry* entry);
|
| + // TabContents ---------------------------------------------------------------
|
|
|
| - // Ensure the given NavigationEntry has a valid state, so that WebKit does
|
| - // not get confused.
|
| - static void SetContentStateIfEmpty(NavigationEntry* entry);
|
| -
|
| - // Begin the destruction sequence for this NavigationController and all its
|
| - // registered tabs. The sequence is as follows:
|
| - // 1. All tabs are asked to Destroy themselves.
|
| - // 2. When each tab is finished Destroying, it will notify the controller.
|
| - // 3. Once all tabs are Destroyed, the NavigationController deletes itself.
|
| - // This ensures that all the TabContents outlive the NavigationController.
|
| - void Destroy();
|
| -
|
| // Notifies the controller that a TabContents that it owns has been destroyed.
|
| // This is part of the NavigationController's Destroy sequence.
|
| void TabContentsWasDestroyed(TabContentsType type);
|
|
|
| + // Returns the TabContents cached on this controller for the given type or
|
| + // NULL if there is none.
|
| + TabContents* GetTabContents(TabContentsType type);
|
| +
|
| // Returns the currently-active TabContents associated with this controller.
|
| // You should use GetActiveEntry instead of this in most cases.
|
| TabContents* active_contents() const {
|
| return active_contents_;
|
| }
|
|
|
| - // This can never be null.
|
| - Profile* profile() const {
|
| - return profile_;
|
| - }
|
| + // For use by TabContents ----------------------------------------------------
|
|
|
| - // Returns the TabContents cached on this controller for the given type or
|
| - // NULL if there is none.
|
| - TabContents* GetTabContents(TabContentsType type);
|
| + // Handles updating the navigation state after the renderer has navigated.
|
| + // This is used by the WebContents. Simpler tab contents types can use
|
| + // CommitPendingEntry below.
|
| + //
|
| + // If a new entry is created, it will return true and will have filled the
|
| + // given details structure and broadcast the NOTIFY_NAV_ENTRY_COMMITTED
|
| + // notification. The caller can then use the details without worrying about
|
| + // listening for the notification.
|
| + //
|
| + // In the case that nothing has changed, the details structure is undefined
|
| + // and it will return false.
|
| + bool RendererDidNavigate(const ViewHostMsg_FrameNavigate_Params& params,
|
| + bool is_interstitial,
|
| + LoadCommittedDetails* details);
|
|
|
| - // Causes the controller to load the specified URL.
|
| - void LoadURL(const GURL& url, PageTransition::Type type);
|
| + // Inserts a new entry by making a copy of the given navigation entry. This is
|
| + // used by interstitials to create dummy entries that they will be in charge
|
| + // of removing later.
|
| + void AddDummyEntryForInterstitial(const NavigationEntry& clone_me);
|
|
|
| - // Causes the controller to load the specified URL the next time it becomes
|
| - // active.
|
| - void LoadURLLazily(const GURL& url, PageTransition::Type type,
|
| - const std::wstring& title, SkBitmap* icon);
|
| + // Removes the last entry in the list. This is used by the interstitial code
|
| + // to delete the dummy entry created by AddDummyEntryForInterstitial. If the
|
| + // last entry is the currently committed one, a ENTRY_COMMITTED notification
|
| + // will be broadcast.
|
| + void RemoveLastEntryForInterstitial();
|
|
|
| + // Notifies us that we just became active. This is used by the TabContents
|
| + // so that we know to load URLs that were pending as "lazy" loads.
|
| + void SetActive(bool is_active);
|
| +
|
| + // Broadcasts the NOTIFY_NAV_ENTRY_CHANGED notification for the given entry
|
| + // (which must be at the given index). This will keep things in sync like
|
| + // the saved session.
|
| + void NotifyEntryChanged(const NavigationEntry* entry, int index);
|
| +
|
| + // Returns true if the given URL would be an in-page navigation (i.e. only
|
| + // the reference fragment is different) from the "last committed entry". We do
|
| + // not compare it against the "active entry" since the active entry can be
|
| + // pending and in page navigations only happen on committed pages. If there
|
| + // is no last committed entry, then nothing will be in-page.
|
| + //
|
| + // Special note: if the URLs are the same, it does NOT count as an in-page
|
| + // navigation. Neither does an input URL that has no ref, even if the rest is
|
| + // the same. This may seem weird, but when we're considering whether a
|
| + // navigation happened without loading anything, the same URL would be a
|
| + // reload, while only a different ref would be in-page (pages can't clear
|
| + // refs without reload, only change to "#" which we don't count as empty).
|
| + bool IsURLInPageNavigation(const GURL& url) const;
|
| +
|
| + // Random data ---------------------------------------------------------------
|
| +
|
| // Returns true if this NavigationController is is configured to load a URL
|
| // lazily. If true, use GetLazyTitle() and GetLazyFavIcon() to discover the
|
| // titles and favicons. Since no request was made, this is the only info
|
| @@ -238,34 +311,10 @@
|
| const std::wstring& GetLazyTitle() const;
|
| const SkBitmap& GetLazyFavIcon() const;
|
|
|
| + // TODO(brettw) bug 1324500: move this out of here.
|
| void SetAlternateNavURLFetcher(
|
| AlternateNavURLFetcher* alternate_nav_url_fetcher);
|
|
|
| - // --------------------------------------------------------------------------
|
| - // For use by TabContents implementors:
|
| -
|
| - // Used to inform the NavigationControllerBase of a navigation being committed
|
| - // for a tab. The controller takes ownership of the entry. Any entry located
|
| - // forward to the current entry will be deleted. The new entry becomes the
|
| - // current entry.
|
| - //
|
| - // The details are populated by the caller except for the new NavigationEntry
|
| - // pointer and the previous URL. We will fill these in before using it to
|
| - // broadcast notifications, so it can also be used by the caller.
|
| - //
|
| - // TODO(brettw) bug 1343146: The NavigationController should internally make
|
| - // the entry and the notification details.
|
| - void DidNavigateToEntry(NavigationEntry* entry,
|
| - LoadCommittedDetails* details);
|
| -
|
| - // Calling this may cause the active tab contents to switch if the current
|
| - // entry corresponds to a different tab contents type.
|
| - void DiscardPendingEntry();
|
| -
|
| - // Inserts an entry after the current position, removing all entries after it.
|
| - // The new entry will become the active one.
|
| - void InsertEntry(NavigationEntry* entry);
|
| -
|
| // Returns the identifier used by session restore.
|
| const SessionID& session_id() const { return session_id_; }
|
|
|
| @@ -275,59 +324,98 @@
|
|
|
| SSLManager* ssl_manager() { return &ssl_manager_; }
|
|
|
| - // Broadcasts the NOTIFY_NAV_ENTRY_CHANGED notification for the
|
| - // navigation corresponding to the given page. This will keep things in sync
|
| - // like saved session.
|
| - void NotifyEntryChangedByPageID(TabContentsType type,
|
| - SiteInstance* instance,
|
| - int32 page_id);
|
| -
|
| - void SetActive(bool is_active);
|
| -
|
| - // If this NavigationController was restored from history and the selected
|
| - // page has not loaded, it is loaded.
|
| - void LoadIfNecessary();
|
| -
|
| - // Clone the receiving navigation controller. Only the active tab contents is
|
| - // duplicated. It is created as a child of the provided HWND.
|
| - NavigationController* Clone(HWND hwnd);
|
| -
|
| // Returns true if a reload happens when activated (SetActive(true) is
|
| // invoked). This is true for session/tab restore and cloned tabs.
|
| bool needs_reload() const { return needs_reload_; }
|
|
|
| - // Disables checking for a repost and prompting the user. This is used during
|
| - // testing.
|
| - static void DisablePromptOnRepost();
|
| -
|
| // Returns the largest restored page ID seen in this navigation controller,
|
| // if it was restored from a previous session. (-1 otherwise)
|
| int max_restored_page_id() const { return max_restored_page_id_; }
|
|
|
| - // Returns the index of the specified entry, or -1 if entry is not contained
|
| - // in this NavigationControllerBase.
|
| - int GetIndexOfEntry(const NavigationEntry* entry) const;
|
| + // Disables checking for a repost and prompting the user. This is used during
|
| + // testing.
|
| + static void DisablePromptOnRepost();
|
|
|
| - // Removes the last committed entry.
|
| - void RemoveLastEntry();
|
| -
|
| private:
|
| FRIEND_TEST(NavigationControllerTest, EnforceMaxNavigationCount);
|
| -
|
| class RestoreHelper;
|
| friend class RestoreHelper;
|
| + friend class TabContents; // For invoking OnReservedPageIDRange.
|
|
|
| - // For invoking OnReservedPageIDRange.
|
| - friend class TabContents;
|
| - // For invoking GetMaxPageID.
|
| - friend class WebContents;
|
| - // For invoking GetMaxPageID.
|
| - friend class printing::PrintViewManager;
|
| + // Indicates different types of navigations that can occur that we will handle
|
| + // separately. This is computed by ClassifyNavigation.
|
| + enum NavClass {
|
| + // A new page was navigated in the main frame.
|
| + NAV_NEW_PAGE,
|
|
|
| - // Returns the largest page ID seen. When PageIDs come in larger than
|
| - // this (via DidNavigateToEntry), we know that we've navigated to a new page.
|
| - int GetMaxPageID() const;
|
| + // Renavigating to an existing navigation entry. The entry is guaranteed to
|
| + // exist in the list, or else it would be a new page or IGNORE navigation.
|
| + NAV_EXISTING_PAGE,
|
|
|
| + // The same page has been reloaded as a result of the user requesting
|
| + // navigation to that same page (like pressing Enter in the URL bar). This
|
| + // is not the same as an in-page navigation because we'll actually have a
|
| + // pending entry for the load, which is then meaningless.
|
| + NAV_SAME_PAGE,
|
| +
|
| + // In page navigations are when the reference fragment changes. This will
|
| + // be in the main frame only (we won't even get notified of in-page
|
| + // subframe navigations). It may be for any page, not necessarily the last
|
| + // committed one (for example, whey going back to a page with a ref).
|
| + NAV_IN_PAGE,
|
| +
|
| + // A new subframe was manually navigated by the user. We will create a new
|
| + // NavigationEntry so they can go back to the previous subframe content
|
| + // using the back button.
|
| + NAV_NEW_SUBFRAME,
|
| +
|
| + // A subframe in the page was automatically loaded or navigated to such that
|
| + // a new navigation entry should not be created. There are two cases:
|
| + // 1. Stuff like iframes containing ads that the page loads automatically.
|
| + // The user doesn't want to see these, so we just update the existing
|
| + // navigation entry.
|
| + // 2. Going back/forward to previous subframe navigations. We don't create
|
| + // a new entry here either, just update the last committed entry.
|
| + // These two cases are actually pretty different, they just happen to
|
| + // require almost the same code to handle.
|
| + NAV_AUTO_SUBFRAME,
|
| +
|
| + // Nothing happened. This happens when we get information about a page we
|
| + // don't know anything about. It can also happen when an iframe in a popup
|
| + // navigated to about:blank is navigated. Nothing needs to be done.
|
| + NAV_IGNORE,
|
| + };
|
| +
|
| + // Classifies the given renderer navigation (see the NavigationType enum).
|
| + NavClass ClassifyNavigation(
|
| + const ViewHostMsg_FrameNavigate_Params& params) const;
|
| +
|
| + // Causes the controller to load the specified entry. The function assumes
|
| + // ownership of the pointer since it is put in the navigation list.
|
| + // NOTE: Do not pass an entry that the controller already owns!
|
| + void LoadEntry(NavigationEntry* entry);
|
| +
|
| + // Handlers for the different types of navigation types. They will actually
|
| + // handle the navigations corresponding to the different NavClasses above.
|
| + // They will NOT broadcast the commit notification, that should be handled by
|
| + // the caller.
|
| + //
|
| + // RendererDidNavigateAutoSubframe is special, it may not actually change
|
| + // anything if some random subframe is loaded. It will return true if anything
|
| + // changed, or false if not.
|
| + void RendererDidNavigateToNewPage(
|
| + const ViewHostMsg_FrameNavigate_Params& params);
|
| + void RendererDidNavigateToExistingPage(
|
| + const ViewHostMsg_FrameNavigate_Params& params);
|
| + void RendererDidNavigateToSamePage(
|
| + const ViewHostMsg_FrameNavigate_Params& params);
|
| + void RendererDidNavigateInPage(
|
| + const ViewHostMsg_FrameNavigate_Params& params);
|
| + void RendererDidNavigateNewSubframe(
|
| + const ViewHostMsg_FrameNavigate_Params& params);
|
| + bool RendererDidNavigateAutoSubframe(
|
| + const ViewHostMsg_FrameNavigate_Params& params);
|
| +
|
| // Actually issues the navigation held in pending_entry.
|
| void NavigateToPendingEntry(bool reload);
|
|
|
| @@ -335,11 +423,6 @@
|
| // committed. This will fill in the active entry to the details structure.
|
| void NotifyNavigationEntryCommitted(LoadCommittedDetails* details);
|
|
|
| - // Invoked when entries have been pruned, or removed. For example, if the
|
| - // current entries are [google, digg, yahoo], with the current entry google,
|
| - // and the user types in cnet, then digg and yahoo are pruned.
|
| - void NotifyPrunedEntries();
|
| -
|
| // Invoked when the index of the active entry may have changed.
|
| // The prev_commited_index parameter specifies the previous value
|
| // of the last commited index before this navigation event happened
|
| @@ -355,9 +438,6 @@
|
| // and deleted by this navigation controller
|
| void RegisterTabContents(TabContents* some_contents);
|
|
|
| - // Broadcasts a notification that the given entry changed.
|
| - void NotifyEntryChanged(const NavigationEntry* entry, int index);
|
| -
|
| // Removes the entry at the specified index. Note that you should not remove
|
| // the pending entry or the last committed entry.
|
| void RemoveEntryAtIndex(int index);
|
| @@ -386,15 +466,14 @@
|
| // contents.
|
| void FinishRestore(HWND parent_hwnd, int selected_index);
|
|
|
| + // Inserts an entry after the current position, removing all entries after it.
|
| + // The new entry will become the active one.
|
| + void InsertEntry(NavigationEntry* entry);
|
| +
|
| // Discards the pending entry without updating active_contents_
|
| void DiscardPendingEntryInternal();
|
|
|
| - // Return the index of the entry with the corresponding type, instance, and
|
| - // page_id, or -1 if not found. Use a NULL instance if the type is not
|
| - // TAB_CONTENTS_WEB.
|
| - int GetEntryIndexWithPageID(TabContentsType type,
|
| - SiteInstance* instance,
|
| - int32 page_id) const;
|
| + // ---------------------------------------------------------------------------
|
|
|
| // The user profile associated with this controller
|
| Profile* profile_;
|
| @@ -421,7 +500,7 @@
|
|
|
| // Tab contents. One entry per type used. The tab controller owns
|
| // every tab contents used.
|
| - typedef stdext::hash_map<TabContentsType, TabContents*> TabContentsMap;
|
| + typedef std::map<TabContentsType, TabContents*> TabContentsMap;
|
| TabContentsMap tab_contents_map_;
|
|
|
| // A map of TabContentsType -> TabContentsCollector containing all the
|
| @@ -471,4 +550,3 @@
|
| };
|
|
|
| #endif // CHROME_BROWSER_NAVIGATION_CONTROLLER_H_
|
| -
|
|
|