1/*
2 * Copyright (C) 2013 Apple 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
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef PageLoadState_h
27#define PageLoadState_h
28
29#include <wtf/text/WTFString.h>
30
31namespace WebKit {
32
33class WebPageProxy;
34
35class PageLoadState {
36public:
37    explicit PageLoadState(WebPageProxy&);
38    ~PageLoadState();
39
40    enum class State {
41        Provisional,
42        Committed,
43        Finished
44    };
45
46    class Observer {
47    public:
48        virtual ~Observer() { }
49
50        virtual void willChangeIsLoading() = 0;
51        virtual void didChangeIsLoading() = 0;
52
53        virtual void willChangeTitle() = 0;
54        virtual void didChangeTitle() = 0;
55
56        virtual void willChangeActiveURL() = 0;
57        virtual void didChangeActiveURL() = 0;
58
59        virtual void willChangeHasOnlySecureContent() = 0;
60        virtual void didChangeHasOnlySecureContent() = 0;
61
62        virtual void willChangeEstimatedProgress() = 0;
63        virtual void didChangeEstimatedProgress() = 0;
64
65        virtual void willChangeCanGoBack() = 0;
66        virtual void didChangeCanGoBack() = 0;
67
68        virtual void willChangeCanGoForward() = 0;
69        virtual void didChangeCanGoForward() = 0;
70
71        virtual void willChangeNetworkRequestsInProgress() = 0;
72        virtual void didChangeNetworkRequestsInProgress() = 0;
73    };
74
75    class Transaction {
76        WTF_MAKE_NONCOPYABLE(Transaction);
77    public:
78        Transaction(Transaction&&);
79        ~Transaction();
80
81    private:
82        friend class PageLoadState;
83
84        explicit Transaction(PageLoadState&);
85
86        class Token {
87        public:
88            Token(Transaction& transaction)
89#if !ASSERT_DISABLED
90                : m_pageLoadState(*transaction.m_pageLoadState)
91#endif
92            {
93                transaction.m_pageLoadState->m_mayHaveUncommittedChanges = true;
94            }
95
96#if !ASSERT_DISABLED
97            PageLoadState& m_pageLoadState;
98#endif
99        };
100
101        RefPtr<WebPageProxy> m_webPageProxy;
102        PageLoadState* m_pageLoadState;
103    };
104
105    void addObserver(Observer&);
106    void removeObserver(Observer&);
107
108    Transaction transaction() { return Transaction(*this); }
109    void commitChanges();
110
111    void reset(const Transaction::Token&);
112
113    bool isLoading() const;
114
115    const String& provisionalURL() const { return m_committedState.provisionalURL; }
116    const String& url() const { return m_committedState.url; }
117    const String& unreachableURL() const { return m_committedState.unreachableURL; }
118
119    String activeURL() const;
120
121    bool hasOnlySecureContent() const;
122
123    double estimatedProgress() const;
124    bool networkRequestsInProgress() const { return m_committedState.networkRequestsInProgress; }
125
126    const String& pendingAPIRequestURL() const;
127    void setPendingAPIRequestURL(const Transaction::Token&, const String&);
128    void clearPendingAPIRequestURL(const Transaction::Token&);
129
130    void didStartProvisionalLoad(const Transaction::Token&, const String& url, const String& unreachableURL);
131    void didReceiveServerRedirectForProvisionalLoad(const Transaction::Token&, const String& url);
132    void didFailProvisionalLoad(const Transaction::Token&);
133
134    void didCommitLoad(const Transaction::Token&);
135    void didFinishLoad(const Transaction::Token&);
136    void didFailLoad(const Transaction::Token&);
137
138    void didSameDocumentNavigation(const Transaction::Token&, const String& url);
139
140    void didDisplayOrRunInsecureContent(const Transaction::Token&);
141
142    void setUnreachableURL(const Transaction::Token&, const String&);
143
144    const String& title() const;
145    void setTitle(const Transaction::Token&, const String&);
146
147    bool canGoBack() const;
148    void setCanGoBack(const Transaction::Token&, bool);
149
150    bool canGoForward() const;
151    void setCanGoForward(const Transaction::Token&, bool);
152
153    void didStartProgress(const Transaction::Token&);
154    void didChangeProgress(const Transaction::Token&, double);
155    void didFinishProgress(const Transaction::Token&);
156    void setNetworkRequestsInProgress(const Transaction::Token&, bool);
157
158private:
159    void beginTransaction() { ++m_outstandingTransactionCount; }
160    void endTransaction();
161
162    void callObserverCallback(void (Observer::*)());
163
164    Vector<Observer*> m_observers;
165
166    struct Data {
167        Data()
168            : state(State::Finished)
169            , hasInsecureContent(false)
170            , canGoBack(false)
171            , canGoForward(false)
172            , estimatedProgress(0)
173            , networkRequestsInProgress(false)
174        {
175        }
176
177        State state;
178        bool hasInsecureContent;
179
180        String pendingAPIRequestURL;
181
182        String provisionalURL;
183        String url;
184
185        String unreachableURL;
186
187        String title;
188
189        bool canGoBack;
190        bool canGoForward;
191
192        double estimatedProgress;
193        bool networkRequestsInProgress;
194    };
195
196    static bool isLoading(const Data&);
197    static String activeURL(const Data&);
198    static bool hasOnlySecureContent(const Data&);
199    static double estimatedProgress(const Data&);
200
201    WebPageProxy& m_webPageProxy;
202
203    Data m_committedState;
204    Data m_uncommittedState;
205
206    String m_lastUnreachableURL;
207
208    bool m_mayHaveUncommittedChanges;
209    unsigned m_outstandingTransactionCount;
210};
211
212} // namespace WebKit
213
214#endif // PageLoadState_h
215