1/*
2 * Copyright (C) 2017 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21#include "WebKitNavigationClient.h"
22
23#include "APINavigationAction.h"
24#include "APINavigationClient.h"
25#include "WebKitBackForwardListPrivate.h"
26#include "WebKitNavigationPolicyDecisionPrivate.h"
27#include "WebKitPrivate.h"
28#include "WebKitResponsePolicyDecisionPrivate.h"
29#include "WebKitURIResponsePrivate.h"
30#include "WebKitWebViewPrivate.h"
31#include <wtf/glib/GUniquePtr.h>
32#include <wtf/text/CString.h>
33
34using namespace WebKit;
35using namespace WebCore;
36
37class NavigationClient : public API::NavigationClient {
38public:
39 explicit NavigationClient(WebKitWebView* webView)
40 : m_webView(webView)
41 {
42 }
43
44private:
45 void didStartProvisionalNavigation(WebPageProxy&, API::Navigation*, API::Object* /* userData */) override
46 {
47 webkitWebViewLoadChanged(m_webView, WEBKIT_LOAD_STARTED);
48 }
49
50 void didReceiveServerRedirectForProvisionalNavigation(WebPageProxy&, API::Navigation*, API::Object* /* userData */) override
51 {
52 webkitWebViewLoadChanged(m_webView, WEBKIT_LOAD_REDIRECTED);
53 }
54
55 void didFailProvisionalNavigationWithError(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, const ResourceError& resourceError, API::Object* /* userData */) override
56 {
57 if (!frame.isMainFrame())
58 return;
59 GUniquePtr<GError> error(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()),
60 toWebKitError(resourceError.errorCode()), resourceError.localizedDescription().utf8().data()));
61 if (resourceError.tlsErrors()) {
62 webkitWebViewLoadFailedWithTLSErrors(m_webView, resourceError.failingURL().string().utf8().data(), error.get(),
63 static_cast<GTlsCertificateFlags>(resourceError.tlsErrors()), resourceError.certificate());
64 } else
65 webkitWebViewLoadFailed(m_webView, WEBKIT_LOAD_STARTED, resourceError.failingURL().string().utf8().data(), error.get());
66 }
67
68 void didCommitNavigation(WebPageProxy&, API::Navigation*, API::Object* /* userData */) override
69 {
70 webkitWebViewLoadChanged(m_webView, WEBKIT_LOAD_COMMITTED);
71 }
72
73 void didFinishNavigation(WebPageProxy&, API::Navigation*, API::Object* /* userData */) override
74 {
75 webkitWebViewLoadChanged(m_webView, WEBKIT_LOAD_FINISHED);
76 }
77
78 void didFailNavigationWithError(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, const ResourceError& resourceError, API::Object* /* userData */) override
79 {
80 if (!frame.isMainFrame())
81 return;
82 GUniquePtr<GError> error(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()),
83 toWebKitError(resourceError.errorCode()), resourceError.localizedDescription().utf8().data()));
84 webkitWebViewLoadFailed(m_webView, WEBKIT_LOAD_COMMITTED, resourceError.failingURL().string().utf8().data(), error.get());
85 }
86
87 void didDisplayInsecureContent(WebPageProxy&, API::Object* /* userData */) override
88 {
89 webkitWebViewInsecureContentDetected(m_webView, WEBKIT_INSECURE_CONTENT_DISPLAYED);
90 }
91
92 void didRunInsecureContent(WebPageProxy&, API::Object* /* userData */) override
93 {
94 webkitWebViewInsecureContentDetected(m_webView, WEBKIT_INSECURE_CONTENT_RUN);
95 }
96
97 bool didChangeBackForwardList(WebPageProxy&, WebBackForwardListItem* addedItem, const Vector<Ref<WebBackForwardListItem>>& removedItems) override
98 {
99 webkitBackForwardListChanged(webkit_web_view_get_back_forward_list(m_webView), addedItem, removedItems);
100 return true;
101 }
102
103 void didReceiveAuthenticationChallenge(WebPageProxy&, AuthenticationChallengeProxy& authenticationChallenge) override
104 {
105 webkitWebViewHandleAuthenticationChallenge(m_webView, &authenticationChallenge);
106 }
107
108 bool processDidTerminate(WebPageProxy&, ProcessTerminationReason reason) override
109 {
110 switch (reason) {
111 case ProcessTerminationReason::Crash:
112 webkitWebViewWebProcessTerminated(m_webView, WEBKIT_WEB_PROCESS_CRASHED);
113 return true;
114 case ProcessTerminationReason::ExceededMemoryLimit:
115 webkitWebViewWebProcessTerminated(m_webView, WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT);
116 return true;
117 case ProcessTerminationReason::ExceededCPULimit:
118 case ProcessTerminationReason::RequestedByClient:
119 case ProcessTerminationReason::NavigationSwap:
120 break;
121 }
122 return false;
123 }
124
125 void decidePolicyForNavigationAction(WebPageProxy&, Ref<API::NavigationAction>&& navigationAction, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* /* userData */) override
126 {
127 WebKitPolicyDecisionType decisionType = navigationAction->targetFrame() ? WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION : WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION;
128 GRefPtr<WebKitPolicyDecision> decision = adoptGRef(webkitNavigationPolicyDecisionCreate(WTFMove(navigationAction), WTFMove(listener)));
129 webkitWebViewMakePolicyDecision(m_webView, decisionType, decision.get());
130 }
131
132 void decidePolicyForNavigationResponse(WebPageProxy&, Ref<API::NavigationResponse>&& navigationResponse, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* /* userData */) override
133 {
134 GRefPtr<WebKitPolicyDecision> decision = adoptGRef(webkitResponsePolicyDecisionCreate(WTFMove(navigationResponse), WTFMove(listener)));
135 webkitWebViewMakePolicyDecision(m_webView, WEBKIT_POLICY_DECISION_TYPE_RESPONSE, decision.get());
136 }
137
138 WebKitWebView* m_webView;
139};
140
141void attachNavigationClientToView(WebKitWebView* webView)
142{
143 webkitWebViewGetPage(webView).setNavigationClient(makeUniqueRef<NavigationClient>(webView));
144}
145
146