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