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