1/*
2 * Copyright (C) 2010 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#include "config.h"
27#include "WebLoaderClient.h"
28
29#include "ImmutableArray.h"
30#include "ImmutableDictionary.h"
31#include "PluginInformation.h"
32#include "WKAPICast.h"
33#include "WebBackForwardListItem.h"
34#include "WebPageProxy.h"
35#include <string.h>
36
37using namespace WebCore;
38
39namespace WebKit {
40
41void WebLoaderClient::didStartProvisionalLoadForFrame(WebPageProxy* page, WebFrameProxy* frame, APIObject* userData)
42{
43    if (!m_client.didStartProvisionalLoadForFrame)
44        return;
45
46    m_client.didStartProvisionalLoadForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.clientInfo);
47}
48
49void WebLoaderClient::didReceiveServerRedirectForProvisionalLoadForFrame(WebPageProxy* page, WebFrameProxy* frame, APIObject* userData)
50{
51    if (!m_client.didReceiveServerRedirectForProvisionalLoadForFrame)
52        return;
53
54    m_client.didReceiveServerRedirectForProvisionalLoadForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.clientInfo);
55}
56
57void WebLoaderClient::didFailProvisionalLoadWithErrorForFrame(WebPageProxy* page, WebFrameProxy* frame, const ResourceError& error, APIObject* userData)
58{
59    if (!m_client.didFailProvisionalLoadWithErrorForFrame)
60        return;
61
62    m_client.didFailProvisionalLoadWithErrorForFrame(toAPI(page), toAPI(frame), toAPI(error), toAPI(userData), m_client.clientInfo);
63}
64
65void WebLoaderClient::didCommitLoadForFrame(WebPageProxy* page, WebFrameProxy* frame, APIObject* userData)
66{
67    if (!m_client.didCommitLoadForFrame)
68        return;
69
70    m_client.didCommitLoadForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.clientInfo);
71}
72
73void WebLoaderClient::didFinishDocumentLoadForFrame(WebPageProxy* page, WebFrameProxy* frame, APIObject* userData)
74{
75    if (!m_client.didFinishDocumentLoadForFrame)
76        return;
77
78    m_client.didFinishDocumentLoadForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.clientInfo);
79}
80
81void WebLoaderClient::didFinishLoadForFrame(WebPageProxy* page, WebFrameProxy* frame, APIObject* userData)
82{
83    if (!m_client.didFinishLoadForFrame)
84        return;
85
86    m_client.didFinishLoadForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.clientInfo);
87}
88
89void WebLoaderClient::didFailLoadWithErrorForFrame(WebPageProxy* page, WebFrameProxy* frame, const ResourceError& error, APIObject* userData)
90{
91    if (!m_client.didFailLoadWithErrorForFrame)
92        return;
93
94    m_client.didFailLoadWithErrorForFrame(toAPI(page), toAPI(frame), toAPI(error), toAPI(userData), m_client.clientInfo);
95}
96
97void WebLoaderClient::didSameDocumentNavigationForFrame(WebPageProxy* page, WebFrameProxy* frame, SameDocumentNavigationType type, APIObject* userData)
98{
99    if (!m_client.didSameDocumentNavigationForFrame)
100        return;
101
102    m_client.didSameDocumentNavigationForFrame(toAPI(page), toAPI(frame), toAPI(type), toAPI(userData), m_client.clientInfo);
103}
104
105void WebLoaderClient::didReceiveTitleForFrame(WebPageProxy* page, const String& title, WebFrameProxy* frame, APIObject* userData)
106{
107    if (!m_client.didReceiveTitleForFrame)
108        return;
109
110    m_client.didReceiveTitleForFrame(toAPI(page), toAPI(title.impl()), toAPI(frame), toAPI(userData), m_client.clientInfo);
111}
112
113void WebLoaderClient::didFirstLayoutForFrame(WebPageProxy* page, WebFrameProxy* frame, APIObject* userData)
114{
115    if (!m_client.didFirstLayoutForFrame)
116        return;
117
118    m_client.didFirstLayoutForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.clientInfo);
119}
120
121void WebLoaderClient::didFirstVisuallyNonEmptyLayoutForFrame(WebPageProxy* page, WebFrameProxy* frame, APIObject* userData)
122{
123    if (!m_client.didFirstVisuallyNonEmptyLayoutForFrame)
124        return;
125
126    m_client.didFirstVisuallyNonEmptyLayoutForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.clientInfo);
127}
128
129void WebLoaderClient::didNewFirstVisuallyNonEmptyLayout(WebPageProxy* page, APIObject* userData)
130{
131    if (!m_client.didNewFirstVisuallyNonEmptyLayout)
132        return;
133
134    m_client.didNewFirstVisuallyNonEmptyLayout(toAPI(page), toAPI(userData), m_client.clientInfo);
135}
136
137void WebLoaderClient::didLayout(WebPageProxy* page, LayoutMilestones milestones, APIObject* userData)
138{
139    if (!m_client.didLayout)
140        return;
141
142    m_client.didLayout(toAPI(page), toWKLayoutMilestones(milestones), toAPI(userData), m_client.clientInfo);
143}
144
145void WebLoaderClient::didRemoveFrameFromHierarchy(WebPageProxy* page, WebFrameProxy* frame, APIObject* userData)
146{
147    if (!m_client.didRemoveFrameFromHierarchy)
148        return;
149
150    m_client.didRemoveFrameFromHierarchy(toAPI(page), toAPI(frame), toAPI(userData), m_client.clientInfo);
151}
152
153void WebLoaderClient::didDisplayInsecureContentForFrame(WebPageProxy* page, WebFrameProxy* frame, APIObject* userData)
154{
155    if (!m_client.didDisplayInsecureContentForFrame)
156        return;
157
158    m_client.didDisplayInsecureContentForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.clientInfo);
159}
160
161void WebLoaderClient::didRunInsecureContentForFrame(WebPageProxy* page, WebFrameProxy* frame, APIObject* userData)
162{
163    if (!m_client.didRunInsecureContentForFrame)
164        return;
165
166    m_client.didRunInsecureContentForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.clientInfo);
167}
168
169void WebLoaderClient::didDetectXSSForFrame(WebPageProxy* page, WebFrameProxy* frame, APIObject* userData)
170{
171    if (!m_client.didDetectXSSForFrame)
172        return;
173
174    m_client.didDetectXSSForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.clientInfo);
175}
176
177bool WebLoaderClient::canAuthenticateAgainstProtectionSpaceInFrame(WebPageProxy* page, WebFrameProxy* frame, WebProtectionSpace* protectionSpace)
178{
179    if (!m_client.canAuthenticateAgainstProtectionSpaceInFrame)
180        return false;
181
182    return m_client.canAuthenticateAgainstProtectionSpaceInFrame(toAPI(page), toAPI(frame), toAPI(protectionSpace), m_client.clientInfo);
183}
184
185void WebLoaderClient::didReceiveAuthenticationChallengeInFrame(WebPageProxy* page, WebFrameProxy* frame, AuthenticationChallengeProxy* authenticationChallenge)
186{
187    if (!m_client.didReceiveAuthenticationChallengeInFrame)
188        return;
189
190    m_client.didReceiveAuthenticationChallengeInFrame(toAPI(page), toAPI(frame), toAPI(authenticationChallenge), m_client.clientInfo);
191}
192
193void WebLoaderClient::didStartProgress(WebPageProxy* page)
194{
195    if (!m_client.didStartProgress)
196        return;
197
198    m_client.didStartProgress(toAPI(page), m_client.clientInfo);
199}
200
201void WebLoaderClient::didChangeProgress(WebPageProxy* page)
202{
203    if (!m_client.didChangeProgress)
204        return;
205
206    m_client.didChangeProgress(toAPI(page), m_client.clientInfo);
207}
208
209void WebLoaderClient::didFinishProgress(WebPageProxy* page)
210{
211    if (!m_client.didFinishProgress)
212        return;
213
214    m_client.didFinishProgress(toAPI(page), m_client.clientInfo);
215}
216
217void WebLoaderClient::processDidBecomeUnresponsive(WebPageProxy* page)
218{
219    if (!m_client.processDidBecomeUnresponsive)
220        return;
221
222    m_client.processDidBecomeUnresponsive(toAPI(page), m_client.clientInfo);
223}
224
225void WebLoaderClient::interactionOccurredWhileProcessUnresponsive(WebPageProxy* page)
226{
227    if (!m_client.interactionOccurredWhileProcessUnresponsive)
228        return;
229
230    m_client.interactionOccurredWhileProcessUnresponsive(toAPI(page), m_client.clientInfo);
231}
232
233void WebLoaderClient::processDidBecomeResponsive(WebPageProxy* page)
234{
235    if (!m_client.processDidBecomeResponsive)
236        return;
237
238    m_client.processDidBecomeResponsive(toAPI(page), m_client.clientInfo);
239}
240
241void WebLoaderClient::processDidCrash(WebPageProxy* page)
242{
243    if (!m_client.processDidCrash)
244        return;
245
246    m_client.processDidCrash(toAPI(page), m_client.clientInfo);
247}
248
249void WebLoaderClient::didChangeBackForwardList(WebPageProxy* page, WebBackForwardListItem* addedItem, Vector<RefPtr<APIObject>>* removedItems)
250{
251    if (!m_client.didChangeBackForwardList)
252        return;
253
254    RefPtr<ImmutableArray> removedItemsArray;
255    if (removedItems && !removedItems->isEmpty())
256        removedItemsArray = ImmutableArray::adopt(*removedItems);
257
258    m_client.didChangeBackForwardList(toAPI(page), toAPI(addedItem), toAPI(removedItemsArray.get()), m_client.clientInfo);
259}
260
261bool WebLoaderClient::shouldGoToBackForwardListItem(WebPageProxy* page, WebBackForwardListItem* item)
262{
263    // We should only even considering sending the shouldGoToBackForwardListItem() client callback
264    // for version 0 clients. Later versioned clients should get willGoToBackForwardListItem() instead,
265    // but due to XPC race conditions this one might have been called instead.
266    if (m_client.version > 0 || !m_client.shouldGoToBackForwardListItem)
267        return true;
268
269    return m_client.shouldGoToBackForwardListItem(toAPI(page), toAPI(item), m_client.clientInfo);
270}
271
272void WebLoaderClient::willGoToBackForwardListItem(WebPageProxy* page, WebBackForwardListItem* item, APIObject* userData)
273{
274    if (m_client.willGoToBackForwardListItem)
275        m_client.willGoToBackForwardListItem(toAPI(page), toAPI(item), toAPI(userData), m_client.clientInfo);
276}
277
278void WebLoaderClient::didFailToInitializePlugin(WebPageProxy* page, ImmutableDictionary* pluginInformation)
279{
280    if (m_client.didFailToInitializePlugin_deprecatedForUseWithV0)
281        m_client.didFailToInitializePlugin_deprecatedForUseWithV0(
282            toAPI(page),
283            toAPI(pluginInformation->get<WebString>(pluginInformationMIMETypeKey())),
284            m_client.clientInfo);
285
286    if (m_client.pluginDidFail_deprecatedForUseWithV1)
287        m_client.pluginDidFail_deprecatedForUseWithV1(
288            toAPI(page),
289            kWKErrorCodeCannotLoadPlugIn,
290            toAPI(pluginInformation->get<WebString>(pluginInformationMIMETypeKey())),
291            0,
292            0,
293            m_client.clientInfo);
294
295    if (m_client.pluginDidFail)
296        m_client.pluginDidFail(
297            toAPI(page),
298            kWKErrorCodeCannotLoadPlugIn,
299            toAPI(pluginInformation),
300            m_client.clientInfo);
301}
302
303void WebLoaderClient::didBlockInsecurePluginVersion(WebPageProxy* page, ImmutableDictionary* pluginInformation)
304{
305    if (m_client.pluginDidFail_deprecatedForUseWithV1)
306        m_client.pluginDidFail_deprecatedForUseWithV1(
307            toAPI(page),
308            kWKErrorCodeInsecurePlugInVersion,
309            toAPI(pluginInformation->get<WebString>(pluginInformationMIMETypeKey())),
310            toAPI(pluginInformation->get<WebString>(pluginInformationBundleIdentifierKey())),
311            toAPI(pluginInformation->get<WebString>(pluginInformationBundleVersionKey())),
312            m_client.clientInfo);
313
314    if (m_client.pluginDidFail)
315        m_client.pluginDidFail(
316            toAPI(page),
317            kWKErrorCodeInsecurePlugInVersion,
318            toAPI(pluginInformation),
319            m_client.clientInfo);
320}
321
322PluginModuleLoadPolicy WebLoaderClient::pluginLoadPolicy(WebPageProxy* page, PluginModuleLoadPolicy currentPluginLoadPolicy, ImmutableDictionary* pluginInformation, String& unavailabilityDescription)
323{
324    WKStringRef unavailabilityDescriptionOut = 0;
325    PluginModuleLoadPolicy loadPolicy = currentPluginLoadPolicy;
326
327    if (m_client.pluginLoadPolicy_deprecatedForUseWithV2)
328        loadPolicy = toPluginModuleLoadPolicy(m_client.pluginLoadPolicy_deprecatedForUseWithV2(toAPI(page), toWKPluginLoadPolicy(currentPluginLoadPolicy), toAPI(pluginInformation), m_client.clientInfo));
329    else if (m_client.pluginLoadPolicy)
330        loadPolicy = toPluginModuleLoadPolicy(m_client.pluginLoadPolicy(toAPI(page), toWKPluginLoadPolicy(currentPluginLoadPolicy), toAPI(pluginInformation), &unavailabilityDescriptionOut, m_client.clientInfo));
331
332    if (unavailabilityDescriptionOut) {
333        RefPtr<WebString> webUnavailabilityDescription = adoptRef(toImpl(unavailabilityDescriptionOut));
334        unavailabilityDescription = webUnavailabilityDescription->string();
335    }
336
337    return loadPolicy;
338}
339
340} // namespace WebKit
341