1/*
2 * Copyright (C) 2011 Igalia S.L.
3 * Portions Copyright (c) 2011 Motorola Mobility, Inc.  All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB.  If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#include "config.h"
22#include "WebKitLoaderClient.h"
23
24#include "WebKitBackForwardListPrivate.h"
25#include "WebKitPrivate.h"
26#include "WebKitURIResponsePrivate.h"
27#include "WebKitWebViewBasePrivate.h"
28#include "WebKitWebViewPrivate.h"
29#include <wtf/gobject/GUniquePtr.h>
30#include <wtf/text/CString.h>
31
32using namespace WebKit;
33using namespace WebCore;
34
35static void didStartProvisionalLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef /* userData */, const void* clientInfo)
36{
37    if (!WKFrameIsMainFrame(frame))
38        return;
39
40    webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_STARTED);
41}
42
43static void didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef /* userData */, const void* clientInfo)
44{
45    if (!WKFrameIsMainFrame(frame))
46        return;
47
48    webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_REDIRECTED);
49}
50
51static void didFailProvisionalLoadWithErrorForFrame(WKPageRef, WKFrameRef frame, WKErrorRef error, WKTypeRef /* userData */, const void* clientInfo)
52{
53    if (!WKFrameIsMainFrame(frame))
54        return;
55
56    const ResourceError& resourceError = toImpl(error)->platformError();
57    GUniquePtr<GError> webError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()),
58        toWebKitError(resourceError.errorCode()), resourceError.localizedDescription().utf8().data()));
59    if (resourceError.tlsErrors()) {
60        webkitWebViewLoadFailedWithTLSErrors(WEBKIT_WEB_VIEW(clientInfo), resourceError.failingURL().utf8().data(), webError.get(),
61            static_cast<GTlsCertificateFlags>(resourceError.tlsErrors()), resourceError.certificate());
62    } else
63        webkitWebViewLoadFailed(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_STARTED, resourceError.failingURL().utf8().data(), webError.get());
64}
65
66static void didCommitLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef /* userData */, const void* clientInfo)
67{
68    if (!WKFrameIsMainFrame(frame))
69        return;
70
71    webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_COMMITTED);
72}
73
74static void didFinishLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef /* userData */, const void* clientInfo)
75{
76    if (!WKFrameIsMainFrame(frame))
77        return;
78
79    webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_FINISHED);
80}
81
82static void didFailLoadWithErrorForFrame(WKPageRef, WKFrameRef frame, WKErrorRef error, WKTypeRef, const void* clientInfo)
83{
84    if (!WKFrameIsMainFrame(frame))
85        return;
86
87    const ResourceError& resourceError = toImpl(error)->platformError();
88    GUniquePtr<GError> webError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()),
89        toWebKitError(resourceError.errorCode()), resourceError.localizedDescription().utf8().data()));
90    webkitWebViewLoadFailed(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_COMMITTED,
91                            resourceError.failingURL().utf8().data(), webError.get());
92}
93
94static void didSameDocumentNavigationForFrame(WKPageRef, WKFrameRef frame, WKSameDocumentNavigationType, WKTypeRef, const void* clientInfo)
95{
96    if (!WKFrameIsMainFrame(frame))
97        return;
98
99    webkitWebViewUpdateURI(WEBKIT_WEB_VIEW(clientInfo));
100}
101
102static void didReceiveTitleForFrame(WKPageRef, WKStringRef titleRef, WKFrameRef frameRef, WKTypeRef, const void* clientInfo)
103{
104    if (!WKFrameIsMainFrame(frameRef))
105        return;
106
107    webkitWebViewSetTitle(WEBKIT_WEB_VIEW(clientInfo), toImpl(titleRef)->string().utf8());
108}
109
110static void didDisplayInsecureContentForFrame(WKPageRef, WKFrameRef, WKTypeRef /* userData */, const void *clientInfo)
111{
112    webkitWebViewInsecureContentDetected(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_INSECURE_CONTENT_DISPLAYED);
113}
114
115static void didRunInsecureContentForFrame(WKPageRef, WKFrameRef, WKTypeRef /* userData */, const void *clientInfo)
116{
117    webkitWebViewInsecureContentDetected(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_INSECURE_CONTENT_RUN);
118}
119
120static void didChangeProgress(WKPageRef page, const void* clientInfo)
121{
122    webkitWebViewSetEstimatedLoadProgress(WEBKIT_WEB_VIEW(clientInfo), WKPageGetEstimatedProgress(page));
123}
124
125static void didChangeBackForwardList(WKPageRef, WKBackForwardListItemRef addedItem, WKArrayRef removedItems, const void* clientInfo)
126{
127    webkitBackForwardListChanged(webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(clientInfo)), toImpl(addedItem), toImpl(removedItems));
128}
129
130static void didReceiveAuthenticationChallengeInFrame(WKPageRef, WKFrameRef, WKAuthenticationChallengeRef authenticationChallenge, const void *clientInfo)
131{
132    webkitWebViewHandleAuthenticationChallenge(WEBKIT_WEB_VIEW(clientInfo), toImpl(authenticationChallenge));
133}
134
135static void processDidCrash(WKPageRef, const void* clientInfo)
136{
137    webkitWebViewWebProcessCrashed(WEBKIT_WEB_VIEW(clientInfo));
138}
139
140void attachLoaderClientToView(WebKitWebView* webView)
141{
142    WKPageLoaderClientV3 wkLoaderClient = {
143        {
144            3, // version
145            webView, // clientInfo
146        },
147        didStartProvisionalLoadForFrame,
148        didReceiveServerRedirectForProvisionalLoadForFrame,
149        didFailProvisionalLoadWithErrorForFrame,
150        didCommitLoadForFrame,
151        0, // didFinishDocumentLoadForFrame
152        didFinishLoadForFrame,
153        didFailLoadWithErrorForFrame,
154        didSameDocumentNavigationForFrame,
155        didReceiveTitleForFrame,
156        0, // didFirstLayoutForFrame
157        0, // didFirstVisuallyNonEmptyLayoutForFrame
158        0, // didRemoveFrameFromHierarchy
159        didDisplayInsecureContentForFrame,
160        didRunInsecureContentForFrame,
161        0, // canAuthenticateAgainstProtectionSpaceInFrame
162        didReceiveAuthenticationChallengeInFrame,
163        didChangeProgress, // didStartProgress
164        didChangeProgress,
165        didChangeProgress, // didFinishProgress
166        0, // didBecomeUnresponsive
167        0, // didBecomeResponsive
168        processDidCrash,
169        didChangeBackForwardList,
170        0, // shouldGoToBackForwardListItem
171        0, // didFailToInitializePlugin
172        0, // didDetectXSSForFrame
173        0, // didFirstVisuallyNonEmptyLayoutForFrame
174        0, // willGoToBackForwardListItem
175        0, // interactionOccurredWhileProcessUnresponsive
176        0, // pluginDidFail_deprecatedForUseWithV1
177        0, // didReceiveIntentForFrame
178        0, // registerIntentServiceForFrame
179        0, // didLayout
180        0, // pluginLoadPolicy_deprecatedForUseWithV2
181        0, // pluginDidFail
182        0, // pluginLoadPolicy
183    };
184    WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
185    WKPageSetPageLoaderClient(wkPage, &wkLoaderClient.base);
186}
187
188