1/*
2 * Copyright (C) 2010, 2011, 2012 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 "InjectedBundlePageLoaderClient.h"
28
29#include "APIArray.h"
30#include "APIData.h"
31#include "APIError.h"
32#include "APIURL.h"
33#include "APIURLRequest.h"
34#include "InjectedBundleDOMWindowExtension.h"
35#include "InjectedBundleScriptWorld.h"
36#include "WKAPICast.h"
37#include "WKBundleAPICast.h"
38#include "WKSharedAPICast.h"
39#include <WebCore/SharedBuffer.h>
40#include <wtf/text/WTFString.h>
41
42using namespace WebCore;
43
44namespace WebKit {
45
46void InjectedBundlePageLoaderClient::willLoadURLRequest(WebPage* page, const ResourceRequest& request, API::Object* userData)
47{
48    if (!m_client.willLoadURLRequest)
49        return;
50
51    m_client.willLoadURLRequest(toAPI(page), toAPI(request), toAPI(userData), m_client.base.clientInfo);
52}
53
54static void releaseSharedBuffer(unsigned char*, const void* data)
55{
56    // Balanced by ref() in InjectedBundlePageLoaderClient::willLoadDataRequest().
57    static_cast<SharedBuffer*>(const_cast<void*>(data))->deref();
58}
59
60void InjectedBundlePageLoaderClient::willLoadDataRequest(WebPage* page, const ResourceRequest& request, SharedBuffer* sharedBuffer, const String& MIMEType, const String& encodingName, const URL& unreachableURL, API::Object* userData)
61{
62    if (!m_client.willLoadDataRequest)
63        return;
64
65    RefPtr<API::Data> data;
66    if (data) {
67        sharedBuffer->ref();
68        data = API::Data::createWithoutCopying((const unsigned char*)sharedBuffer->data(), sharedBuffer->size(), releaseSharedBuffer, sharedBuffer);
69    }
70
71    m_client.willLoadDataRequest(toAPI(page), toAPI(request), toAPI(data.get()), toAPI(MIMEType.impl()), toAPI(encodingName.impl()), toURLRef(unreachableURL.string().impl()), toAPI(userData), m_client.base.clientInfo);
72}
73
74bool InjectedBundlePageLoaderClient::shouldGoToBackForwardListItem(WebPage* page, InjectedBundleBackForwardListItem* item, RefPtr<API::Object>& userData)
75{
76    if (!m_client.shouldGoToBackForwardListItem)
77        return true;
78
79    WKTypeRef userDataToPass = 0;
80    bool result = m_client.shouldGoToBackForwardListItem(toAPI(page), toAPI(item), &userDataToPass, m_client.base.clientInfo);
81    userData = adoptRef(toImpl(userDataToPass));
82
83    return result;
84}
85
86void InjectedBundlePageLoaderClient::didStartProvisionalLoadForFrame(WebPage* page, WebFrame* frame, RefPtr<API::Object>& userData)
87{
88    if (!m_client.didStartProvisionalLoadForFrame)
89        return;
90
91    WKTypeRef userDataToPass = 0;
92    m_client.didStartProvisionalLoadForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.base.clientInfo);
93    userData = adoptRef(toImpl(userDataToPass));
94}
95
96void InjectedBundlePageLoaderClient::didReceiveServerRedirectForProvisionalLoadForFrame(WebPage* page, WebFrame* frame, RefPtr<API::Object>& userData)
97{
98    if (!m_client.didReceiveServerRedirectForProvisionalLoadForFrame)
99        return;
100
101    WKTypeRef userDataToPass = 0;
102    m_client.didReceiveServerRedirectForProvisionalLoadForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.base.clientInfo);
103    userData = adoptRef(toImpl(userDataToPass));
104}
105
106void InjectedBundlePageLoaderClient::didFailProvisionalLoadWithErrorForFrame(WebPage* page, WebFrame* frame, const ResourceError& error, RefPtr<API::Object>& userData)
107{
108    if (!m_client.didFailProvisionalLoadWithErrorForFrame)
109        return;
110
111    WKTypeRef userDataToPass = 0;
112    m_client.didFailProvisionalLoadWithErrorForFrame(toAPI(page), toAPI(frame), toAPI(error), &userDataToPass, m_client.base.clientInfo);
113    userData = adoptRef(toImpl(userDataToPass));
114}
115
116void InjectedBundlePageLoaderClient::didCommitLoadForFrame(WebPage* page, WebFrame* frame, RefPtr<API::Object>& userData)
117{
118    if (!m_client.didCommitLoadForFrame)
119        return;
120
121    WKTypeRef userDataToPass = 0;
122    m_client.didCommitLoadForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.base.clientInfo);
123    userData = adoptRef(toImpl(userDataToPass));
124}
125
126void InjectedBundlePageLoaderClient::didFinishDocumentLoadForFrame(WebPage* page, WebFrame* frame, RefPtr<API::Object>& userData)
127{
128    if (!m_client.didFinishDocumentLoadForFrame)
129        return;
130
131    WKTypeRef userDataToPass = 0;
132    m_client.didFinishDocumentLoadForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.base.clientInfo);
133    userData = adoptRef(toImpl(userDataToPass));
134}
135
136void InjectedBundlePageLoaderClient::didFinishLoadForFrame(WebPage* page, WebFrame* frame, RefPtr<API::Object>& userData)
137{
138    if (!m_client.didFinishLoadForFrame)
139        return;
140
141    WKTypeRef userDataToPass = 0;
142    m_client.didFinishLoadForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.base.clientInfo);
143    userData = adoptRef(toImpl(userDataToPass));
144}
145
146void InjectedBundlePageLoaderClient::didFinishProgress(WebPage* page)
147{
148    if (!m_client.didFinishProgress)
149        return;
150
151    m_client.didFinishProgress(toAPI(page), m_client.base.clientInfo);
152}
153
154void InjectedBundlePageLoaderClient::didFailLoadWithErrorForFrame(WebPage* page, WebFrame* frame, const ResourceError& error, RefPtr<API::Object>& userData)
155{
156    if (!m_client.didFailLoadWithErrorForFrame)
157        return;
158
159    WKTypeRef userDataToPass = 0;
160    m_client.didFailLoadWithErrorForFrame(toAPI(page), toAPI(frame), toAPI(error), &userDataToPass, m_client.base.clientInfo);
161    userData = adoptRef(toImpl(userDataToPass));
162}
163
164void InjectedBundlePageLoaderClient::didSameDocumentNavigationForFrame(WebPage* page, WebFrame* frame, SameDocumentNavigationType type, RefPtr<API::Object>& userData)
165{
166    if (!m_client.didSameDocumentNavigationForFrame)
167        return;
168
169    WKTypeRef userDataToPass = 0;
170    m_client.didSameDocumentNavigationForFrame(toAPI(page), toAPI(frame), toAPI(type), &userDataToPass, m_client.base.clientInfo);
171    userData = adoptRef(toImpl(userDataToPass));
172}
173
174void InjectedBundlePageLoaderClient::didReceiveTitleForFrame(WebPage* page, const String& title, WebFrame* frame, RefPtr<API::Object>& userData)
175{
176    if (!m_client.didReceiveTitleForFrame)
177        return;
178
179    WKTypeRef userDataToPass = 0;
180    m_client.didReceiveTitleForFrame(toAPI(page), toAPI(title.impl()), toAPI(frame), &userDataToPass, m_client.base.clientInfo);
181    userData = adoptRef(toImpl(userDataToPass));
182}
183
184void InjectedBundlePageLoaderClient::didRemoveFrameFromHierarchy(WebPage* page , WebFrame* frame, RefPtr<API::Object>& userData)
185{
186    if (!m_client.didRemoveFrameFromHierarchy)
187        return;
188
189    WKTypeRef userDataToPass = 0;
190    m_client.didRemoveFrameFromHierarchy(toAPI(page), toAPI(frame), &userDataToPass, m_client.base.clientInfo);
191    userData = adoptRef(toImpl(userDataToPass));
192}
193
194void InjectedBundlePageLoaderClient::didDisplayInsecureContentForFrame(WebPage* page, WebFrame* frame, RefPtr<API::Object>& userData)
195{
196    if (!m_client.didDisplayInsecureContentForFrame)
197        return;
198
199    WKTypeRef userDataToPass = 0;
200    m_client.didDisplayInsecureContentForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.base.clientInfo);
201    userData = adoptRef(toImpl(userDataToPass));
202}
203
204void InjectedBundlePageLoaderClient::didRunInsecureContentForFrame(WebPage* page, WebFrame* frame, RefPtr<API::Object>& userData)
205{
206    if (!m_client.didRunInsecureContentForFrame)
207        return;
208
209    WKTypeRef userDataToPass = 0;
210    m_client.didRunInsecureContentForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.base.clientInfo);
211    userData = adoptRef(toImpl(userDataToPass));
212}
213
214void InjectedBundlePageLoaderClient::didDetectXSSForFrame(WebPage* page, WebFrame* frame, RefPtr<API::Object>& userData)
215{
216    if (!m_client.didDetectXSSForFrame)
217        return;
218
219    WKTypeRef userDataToPass = 0;
220    m_client.didDetectXSSForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.base.clientInfo);
221    userData = adoptRef(toImpl(userDataToPass));
222}
223
224void InjectedBundlePageLoaderClient::didFirstLayoutForFrame(WebPage* page, WebFrame* frame, RefPtr<API::Object>& userData)
225{
226    if (!m_client.didFirstLayoutForFrame)
227        return;
228
229    WKTypeRef userDataToPass = 0;
230    m_client.didFirstLayoutForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.base.clientInfo);
231    userData = adoptRef(toImpl(userDataToPass));
232}
233
234void InjectedBundlePageLoaderClient::didFirstVisuallyNonEmptyLayoutForFrame(WebPage* page, WebFrame* frame, RefPtr<API::Object>& userData)
235{
236    if (!m_client.didFirstVisuallyNonEmptyLayoutForFrame)
237        return;
238
239    WKTypeRef userDataToPass = 0;
240    m_client.didFirstVisuallyNonEmptyLayoutForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.base.clientInfo);
241    userData = adoptRef(toImpl(userDataToPass));
242}
243
244void InjectedBundlePageLoaderClient::didLayoutForFrame(WebPage* page, WebFrame* frame)
245{
246    if (!m_client.didLayoutForFrame)
247        return;
248
249    m_client.didLayoutForFrame(toAPI(page), toAPI(frame), m_client.base.clientInfo);
250}
251
252void InjectedBundlePageLoaderClient::didLayout(WebPage* page, LayoutMilestones milestones, RefPtr<API::Object>& userData)
253{
254    if (!m_client.didLayout)
255        return;
256
257    WKTypeRef userDataToPass = 0;
258    m_client.didLayout(toAPI(page), toWKLayoutMilestones(milestones), &userDataToPass, m_client.base.clientInfo);
259    userData = adoptRef(toImpl(userDataToPass));
260}
261
262void InjectedBundlePageLoaderClient::didClearWindowObjectForFrame(WebPage* page, WebFrame* frame, DOMWrapperWorld& world)
263{
264    if (!m_client.didClearWindowObjectForFrame)
265        return;
266
267    m_client.didClearWindowObjectForFrame(toAPI(page), toAPI(frame), toAPI(InjectedBundleScriptWorld::getOrCreate(world).get()), m_client.base.clientInfo);
268}
269
270void InjectedBundlePageLoaderClient::didCancelClientRedirectForFrame(WebPage* page, WebFrame* frame)
271{
272    if (!m_client.didCancelClientRedirectForFrame)
273        return;
274
275    m_client.didCancelClientRedirectForFrame(toAPI(page), toAPI(frame), m_client.base.clientInfo);
276}
277
278void InjectedBundlePageLoaderClient::willPerformClientRedirectForFrame(WebPage* page, WebFrame* frame, const String& url, double delay, double date)
279{
280    if (!m_client.willPerformClientRedirectForFrame)
281        return;
282
283    m_client.willPerformClientRedirectForFrame(toAPI(page), toAPI(frame), toURLRef(url.impl()), delay, date, m_client.base.clientInfo);
284}
285
286void InjectedBundlePageLoaderClient::didHandleOnloadEventsForFrame(WebPage* page, WebFrame* frame)
287{
288    if (!m_client.didHandleOnloadEventsForFrame)
289        return;
290
291    m_client.didHandleOnloadEventsForFrame(toAPI(page), toAPI(frame), m_client.base.clientInfo);
292}
293
294void InjectedBundlePageLoaderClient::globalObjectIsAvailableForFrame(WebPage* page, WebFrame* frame, WebCore::DOMWrapperWorld& world)
295{
296    if (!m_client.globalObjectIsAvailableForFrame)
297        return;
298
299    RefPtr<InjectedBundleScriptWorld> injectedWorld = InjectedBundleScriptWorld::getOrCreate(world);
300    m_client.globalObjectIsAvailableForFrame(toAPI(page), toAPI(frame), toAPI(injectedWorld.get()), m_client.base.clientInfo);
301}
302
303void InjectedBundlePageLoaderClient::willDisconnectDOMWindowExtensionFromGlobalObject(WebPage* page, WebCore::DOMWindowExtension* coreExtension)
304{
305    if (!m_client.willDisconnectDOMWindowExtensionFromGlobalObject)
306        return;
307
308    RefPtr<InjectedBundleDOMWindowExtension> extension = InjectedBundleDOMWindowExtension::get(coreExtension);
309    ASSERT(extension);
310    m_client.willDisconnectDOMWindowExtensionFromGlobalObject(toAPI(page), toAPI(extension.get()), m_client.base.clientInfo);
311}
312
313void InjectedBundlePageLoaderClient::didReconnectDOMWindowExtensionToGlobalObject(WebPage* page, WebCore::DOMWindowExtension* coreExtension)
314{
315    if (!m_client.didReconnectDOMWindowExtensionToGlobalObject)
316        return;
317
318    RefPtr<InjectedBundleDOMWindowExtension> extension = InjectedBundleDOMWindowExtension::get(coreExtension);
319    ASSERT(extension);
320    m_client.didReconnectDOMWindowExtensionToGlobalObject(toAPI(page), toAPI(extension.get()), m_client.base.clientInfo);
321}
322
323void InjectedBundlePageLoaderClient::willDestroyGlobalObjectForDOMWindowExtension(WebPage* page, WebCore::DOMWindowExtension* coreExtension)
324{
325    if (!m_client.willDestroyGlobalObjectForDOMWindowExtension)
326        return;
327
328    RefPtr<InjectedBundleDOMWindowExtension> extension = InjectedBundleDOMWindowExtension::get(coreExtension);
329    ASSERT(extension);
330    m_client.willDestroyGlobalObjectForDOMWindowExtension(toAPI(page), toAPI(extension.get()), m_client.base.clientInfo);
331}
332
333bool InjectedBundlePageLoaderClient::shouldForceUniversalAccessFromLocalURL(WebPage* page, const String& url)
334{
335    if (!m_client.shouldForceUniversalAccessFromLocalURL)
336        return false;
337
338    return m_client.shouldForceUniversalAccessFromLocalURL(toAPI(page), toAPI(url.impl()), m_client.base.clientInfo);
339}
340
341void InjectedBundlePageLoaderClient::featuresUsedInPage(WebPage* page, const Vector<String>& features)
342{
343    if (!m_client.featuresUsedInPage)
344        return;
345
346    return m_client.featuresUsedInPage(toAPI(page), toAPI(API::Array::createStringArray(features).get()), m_client.base.clientInfo);
347}
348
349void InjectedBundlePageLoaderClient::willDestroyFrame(WebPage* page, WebFrame* frame)
350{
351    if (!m_client.willDestroyFrame)
352        return;
353
354    m_client.willDestroyFrame(toAPI(page), toAPI(frame), m_client.base.clientInfo);
355}
356
357API::String* InjectedBundlePageLoaderClient::userAgentForURL(WebFrame* frame, API::URL* url) const
358{
359    if (!m_client.userAgentForURL)
360        return nullptr;
361    WKStringRef userAgent = m_client.userAgentForURL(toAPI(frame), toAPI(url), m_client.base.clientInfo);
362    return toImpl(userAgent);
363}
364
365} // namespace WebKit
366