1/*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#ifndef TestNavigationController_h
32#define TestNavigationController_h
33
34#include "WebDataSource.h"
35#include "WebHistoryItem.h"
36#include "WebString.h"
37#include "WebURL.h"
38#include "webkit/support/webkit_support.h"
39#include <string>
40#include <wtf/RefCounted.h>
41#include <wtf/RefPtr.h>
42#include <wtf/Vector.h>
43
44// Associated with browser-initated navigations to hold tracking data.
45class TestShellExtraData : public WebKit::WebDataSource::ExtraData {
46public:
47    TestShellExtraData(int32_t pendingPageID)
48        : pendingPageID(pendingPageID)
49        , requestCommitted(false) {}
50
51    // Contains the page_id for this navigation or -1 if there is none yet.
52    int32_t pendingPageID;
53
54    // True if we have already processed the "DidCommitLoad" event for this
55    // request. Used by session history.
56    bool requestCommitted;
57};
58
59// Stores one back/forward navigation state for the test shell.
60class TestNavigationEntry: public RefCounted<TestNavigationEntry> {
61public:
62    static PassRefPtr<TestNavigationEntry> create();
63    static PassRefPtr<TestNavigationEntry> create(
64        int pageID,
65        const WebKit::WebURL&,
66        const WebKit::WebString& title,
67        const WebKit::WebString& targetFrame);
68
69    // Virtual to allow test_shell to extend the class.
70    virtual ~TestNavigationEntry();
71
72    // Set / Get the URI
73    void setURL(const WebKit::WebURL& url) { m_url = url; }
74    const WebKit::WebURL& URL() const { return m_url; }
75
76    // Set / Get the title
77    void setTitle(const WebKit::WebString& title) { m_title = title; }
78    const WebKit::WebString& title() const { return m_title; }
79
80    // Set / Get a state.
81    void setContentState(const WebKit::WebHistoryItem&);
82    const WebKit::WebHistoryItem& contentState() const { return m_state; }
83
84    // Get the page id corresponding to the tab's state.
85    void setPageID(int pageID) { m_pageID = pageID; }
86    int32_t pageID() const { return m_pageID; }
87
88    const WebKit::WebString& targetFrame() const { return m_targetFrame; }
89
90private:
91    TestNavigationEntry();
92    TestNavigationEntry(int pageID,
93                        const WebKit::WebURL&,
94                        const WebKit::WebString& title,
95                        const WebKit::WebString& targetFrame);
96
97    // Describes the current page that the tab represents. This is not relevant
98    // for all tab contents types.
99    int32_t m_pageID;
100
101    WebKit::WebURL m_url;
102    WebKit::WebString m_title;
103    WebKit::WebHistoryItem m_state;
104    WebKit::WebString m_targetFrame;
105};
106
107class NavigationHost {
108public:
109    virtual bool navigate(const TestNavigationEntry&, bool reload) = 0;
110};
111
112// Test shell's NavigationController. The goal is to be as close to the Chrome
113// version as possible.
114class TestNavigationController {
115    WTF_MAKE_NONCOPYABLE(TestNavigationController);
116public:
117    TestNavigationController(NavigationHost*);
118    ~TestNavigationController();
119
120    void reset();
121
122    // Causes the controller to reload the current (or pending) entry.
123    void reload();
124
125    // Causes the controller to go to the specified offset from current. Does
126    // nothing if out of bounds.
127    void goToOffset(int);
128
129    // Causes the controller to go to the specified index.
130    void goToIndex(int);
131
132    // Causes the controller to load the specified entry.
133    // NOTE: Do not pass an entry that the controller already owns!
134    void loadEntry(TestNavigationEntry*);
135
136    // Returns the last committed entry, which may be null if there are no
137    // committed entries.
138    TestNavigationEntry* lastCommittedEntry() const;
139
140    // Returns the number of entries in the NavigationControllerBase, excluding
141    // the pending entry if there is one.
142    int entryCount() const { return static_cast<int>(m_entries.size()); }
143
144    // Returns the active entry, which is the pending entry if a navigation is in
145    // progress or the last committed entry otherwise.  NOTE: This can be 0!!
146    //
147    // If you are trying to get the current state of the NavigationControllerBase,
148    // this is the method you will typically want to call.
149    TestNavigationEntry* activeEntry() const;
150
151    // Returns the index from which we would go back/forward or reload. This is
152    // the m_lastCommittedEntryIndex if m_pendingEntryIndex is -1. Otherwise,
153    // it is the m_pendingEntryIndex.
154    int currentEntryIndex() const;
155
156    // Returns the entry at the specified index.  Returns 0 if out of
157    // bounds.
158    TestNavigationEntry* entryAtIndex(int) const;
159
160    // Return the entry with the corresponding type and page ID, or 0 if
161    // not found.
162    TestNavigationEntry* entryWithPageID(int32_t) const;
163
164    // Returns the index of the last committed entry.
165    int lastCommittedEntryIndex() const { return m_lastCommittedEntryIndex; }
166
167    // Used to inform us of a navigation being committed for a tab. Any entry
168    // located forward to the current entry will be deleted. The new entry
169    // becomes the current entry.
170    void didNavigateToEntry(TestNavigationEntry*);
171
172    // Used to inform us to discard its pending entry.
173    void discardPendingEntry();
174
175private:
176    // Inserts an entry after the current position, removing all entries after it.
177    // The new entry will become the active one.
178    void insertEntry(TestNavigationEntry*);
179
180    int maxPageID() const { return m_maxPageID; }
181    void navigateToPendingEntry(bool reload);
182
183    // Return the index of the entry with the corresponding type and page ID,
184    // or -1 if not found.
185    int entryIndexWithPageID(int32_t) const;
186
187    // Updates the max page ID with that of the given entry, if is larger.
188    void updateMaxPageID();
189
190    // List of NavigationEntry for this tab
191    typedef Vector<RefPtr<TestNavigationEntry> > NavigationEntryList;
192    typedef NavigationEntryList::iterator NavigationEntryListIterator;
193    NavigationEntryList m_entries;
194
195    // An entry we haven't gotten a response for yet.  This will be discarded
196    // when we navigate again.  It's used only so we know what the currently
197    // displayed tab is.
198    RefPtr<TestNavigationEntry> m_pendingEntry;
199
200    // currently visible entry
201    int m_lastCommittedEntryIndex;
202
203    // index of pending entry if it is in entries_, or -1 if pending_entry_ is a
204    // new entry (created by LoadURL).
205    int m_pendingEntryIndex;
206
207    NavigationHost* m_host;
208    int m_maxPageID;
209};
210
211#endif // TestNavigationController_h
212
213