1/*
2 * Copyright (C) 2014 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 NavigationState_h
27#define NavigationState_h
28
29#import "WKFoundation.h"
30
31#if WK_API_ENABLED
32
33#import <wtf/HashMap.h>
34#import <wtf/RetainPtr.h>
35#import "APILoaderClient.h"
36#import "APIPolicyClient.h"
37#import "PageLoadState.h"
38#import "ProcessThrottler.h"
39#import "WeakObjCPtr.h"
40
41@class WKNavigation;
42@class WKWebView;
43@protocol WKHistoryDelegatePrivate;
44@protocol WKNavigationDelegate;
45
46namespace WebKit {
47
48struct WebNavigationDataStore;
49
50class NavigationState : private PageLoadState::Observer {
51public:
52    explicit NavigationState(WKWebView *);
53    ~NavigationState();
54
55    static NavigationState& fromWebPage(WebPageProxy&);
56
57    std::unique_ptr<API::PolicyClient> createPolicyClient();
58    std::unique_ptr<API::LoaderClient> createLoaderClient();
59
60    RetainPtr<id <WKNavigationDelegate> > navigationDelegate();
61    void setNavigationDelegate(id <WKNavigationDelegate>);
62
63    RetainPtr<id <WKHistoryDelegatePrivate> > historyDelegate();
64    void setHistoryDelegate(id <WKHistoryDelegatePrivate>);
65
66    RetainPtr<WKNavigation> createBackForwardNavigation(uint64_t navigationID, const WebBackForwardListItem&);
67    RetainPtr<WKNavigation> createLoadRequestNavigation(uint64_t navigationID, NSURLRequest *);
68    RetainPtr<WKNavigation> createReloadNavigation(uint64_t navigationID);
69    RetainPtr<WKNavigation> createLoadDataNavigation(uint64_t navigationID);
70
71    // Called by the history client.
72    void didNavigateWithNavigationData(const WebKit::WebNavigationDataStore&);
73    void didPerformClientRedirect(const WTF::String& sourceURL, const WTF::String& destinationURL);
74    void didPerformServerRedirect(const WTF::String& sourceURL, const WTF::String& destinationURL);
75    void didUpdateHistoryTitle(const WTF::String& title, const WTF::String& url);
76
77    // Called by the page client.
78    void navigationGestureDidBegin();
79    void navigationGestureWillEnd(bool willNavigate, WebBackForwardListItem&);
80    void navigationGestureDidEnd(bool willNavigate, WebBackForwardListItem&);
81    void willRecordNavigationSnapshot(WebBackForwardListItem&);
82
83private:
84    class PolicyClient : public API::PolicyClient {
85    public:
86        explicit PolicyClient(NavigationState&);
87        ~PolicyClient();
88
89    private:
90        // API::PolicyClient
91        virtual void decidePolicyForNavigationAction(WebPageProxy*, WebFrameProxy* destinationFrame, const NavigationActionData&, WebFrameProxy* sourceFrame, const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceRequest&, RefPtr<WebFramePolicyListenerProxy>, API::Object* userData) override;
92        virtual void decidePolicyForNewWindowAction(WebPageProxy*, WebFrameProxy* sourceFrame, const NavigationActionData&, const WebCore::ResourceRequest&, const WTF::String& frameName, RefPtr<WebFramePolicyListenerProxy>, API::Object* userData) override;
93        virtual void decidePolicyForResponse(WebPageProxy*, WebFrameProxy*, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, RefPtr<WebFramePolicyListenerProxy>, API::Object* userData) override;
94
95        NavigationState& m_navigationState;
96    };
97
98    class LoaderClient : public API::LoaderClient {
99    public:
100        explicit LoaderClient(NavigationState&);
101        ~LoaderClient();
102
103    private:
104        virtual void didStartProvisionalLoadForFrame(WebPageProxy*, WebFrameProxy*, uint64_t navigationID, API::Object*) override;
105        virtual void didReceiveServerRedirectForProvisionalLoadForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, uint64_t navigationID, API::Object*);
106        virtual void didFailProvisionalLoadWithErrorForFrame(WebPageProxy*, WebFrameProxy*, uint64_t navigationID, const WebCore::ResourceError&, API::Object*) override;
107        virtual void didCommitLoadForFrame(WebPageProxy*, WebFrameProxy*, uint64_t navigationID, API::Object*) override;
108        virtual void didFinishDocumentLoadForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, uint64_t navigationID, API::Object*) override;
109        virtual void didFinishLoadForFrame(WebPageProxy*, WebFrameProxy*, uint64_t navigationID, API::Object*) override;
110        virtual void didFailLoadWithErrorForFrame(WebPageProxy*, WebFrameProxy*, uint64_t navigationID, const WebCore::ResourceError&, API::Object*) override;
111        virtual void didSameDocumentNavigationForFrame(WebPageProxy*, WebFrameProxy*, uint64_t navigationID, SameDocumentNavigationType, API::Object*) override;
112        virtual void didDestroyNavigation(WebKit::WebPageProxy*, uint64_t navigationID) override;
113        virtual void didLayout(WebKit::WebPageProxy*, WebCore::LayoutMilestones, API::Object*) override;
114        virtual bool canAuthenticateAgainstProtectionSpaceInFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, WebKit::WebProtectionSpace*) override;
115        virtual void didReceiveAuthenticationChallengeInFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, WebKit::AuthenticationChallengeProxy*) override;
116        virtual void processDidCrash(WebKit::WebPageProxy*) override;
117        virtual PassRefPtr<API::Data> webCryptoMasterKey(WebKit::WebPageProxy&) override;
118#if USE(QUICK_LOOK)
119        virtual void didStartLoadForQuickLookDocumentInMainFrame(const WTF::String& fileName, const WTF::String& uti) override;
120        virtual void didFinishLoadForQuickLookDocumentInMainFrame(const WebKit::QuickLookDocumentData&) override;
121#endif
122
123        NavigationState& m_navigationState;
124    };
125
126    // PageLoadState::Observer
127    virtual void willChangeIsLoading() override;
128    virtual void didChangeIsLoading() override;
129    virtual void willChangeTitle() override;
130    virtual void didChangeTitle() override;
131    virtual void willChangeActiveURL() override;
132    virtual void didChangeActiveURL() override;
133    virtual void willChangeHasOnlySecureContent() override;
134    virtual void didChangeHasOnlySecureContent() override;
135    virtual void willChangeEstimatedProgress() override;
136    virtual void didChangeEstimatedProgress() override;
137    virtual void willChangeCanGoBack() override;
138    virtual void didChangeCanGoBack() override;
139    virtual void willChangeCanGoForward() override;
140    virtual void didChangeCanGoForward() override;
141    virtual void willChangeNetworkRequestsInProgress() override;
142    virtual void didChangeNetworkRequestsInProgress() override;
143
144    WKWebView *m_webView;
145    WeakObjCPtr<id <WKNavigationDelegate> > m_navigationDelegate;
146
147    struct {
148        bool webViewDecidePolicyForNavigationActionDecisionHandler : 1;
149        bool webViewDecidePolicyForNavigationResponseDecisionHandler : 1;
150
151        bool webViewDidStartProvisionalNavigation : 1;
152        bool webViewDidReceiveServerRedirectForProvisionalNavigation : 1;
153        bool webViewDidFailProvisionalNavigationWithError : 1;
154        bool webViewNavigationDidFailProvisionalLoadInSubframeWithError : 1;
155        bool webViewDidCommitNavigation : 1;
156        bool webViewNavigationDidFinishDocumentLoad : 1;
157        bool webViewDidFinishNavigation : 1;
158        bool webViewDidFailNavigationWithError : 1;
159        bool webViewNavigationDidSameDocumentNavigation : 1;
160
161        bool webViewRenderingProgressDidChange : 1;
162        bool webViewDidReceiveAuthenticationChallengeCompletionHandler : 1;
163        bool webViewCanAuthenticateAgainstProtectionSpace : 1;
164        bool webViewDidReceiveAuthenticationChallenge : 1;
165        bool webViewWebProcessDidCrash : 1;
166        bool webCryptoMasterKeyForWebView : 1;
167        bool webViewDidBeginNavigationGesture : 1;
168        bool webViewWillEndNavigationGestureWithNavigationToBackForwardListItem : 1;
169        bool webViewDidEndNavigationGestureWithNavigationToBackForwardListItem : 1;
170        bool webViewWillSnapshotBackForwardListItem : 1;
171#if USE(QUICK_LOOK)
172        bool webViewDidStartLoadForQuickLookDocumentInMainFrame : 1;
173        bool webViewDidFinishLoadForQuickLookDocumentInMainFrame : 1;
174#endif
175    } m_navigationDelegateMethods;
176
177    HashMap<uint64_t, RetainPtr<WKNavigation>> m_navigations;
178
179    WeakObjCPtr<id <WKHistoryDelegatePrivate> > m_historyDelegate;
180    struct {
181        bool webViewDidNavigateWithNavigationData : 1;
182        bool webViewDidPerformClientRedirectFromURLToURL : 1;
183        bool webViewDidPerformServerRedirectFromURLToURL : 1;
184        bool webViewDidUpdateHistoryTitleForURL : 1;
185    } m_historyDelegateMethods;
186
187#if PLATFORM(IOS)
188    std::unique_ptr<ProcessThrottler::BackgroundActivityToken> m_activityToken;
189#endif
190};
191
192} // namespace WebKit
193
194#endif
195
196#endif // NavigationState_h
197