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 | |
44 | namespace WebKit { |
45 | using namespace WebCore; |
46 | |
47 | InjectedBundlePageLoaderClient::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 | |
56 | void 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 | |
64 | static 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 | |
70 | void 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 | |
84 | void 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 | |
94 | void 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 | |
104 | void 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 | |
114 | void 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 | |
124 | void 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 | |
134 | void 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 | |
144 | void 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 | |
152 | void 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 | |
162 | void 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 | |
172 | void 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 | |
182 | void 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 | |
192 | void 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 | |
202 | void 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 | |
212 | void 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 | |
222 | void 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 | |
232 | void 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 | |
242 | void 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 | |
250 | void 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 | |
260 | void 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 | |
268 | void 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 | |
276 | void 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 | |
284 | void 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 | |
292 | void 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 | |
301 | void 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 | |
310 | void 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 | |
320 | void 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 | |
330 | void 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 | |
340 | bool 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 | |
348 | void 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 | |
356 | OptionSet<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 | |