8a7594e013b2317a3a327babd4492f934e201dbd
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebCoreSupport / WebFrameLoaderClient.cpp
1 /*
2  * Copyright (C) 2010-2016 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 "WebFrameLoaderClient.h"
28
29 #include "AuthenticationManager.h"
30 #include "DataReference.h"
31 #include "DrawingArea.h"
32 #include "InjectedBundle.h"
33 #include "InjectedBundleBackForwardListItem.h"
34 #include "InjectedBundleDOMWindowExtension.h"
35 #include "InjectedBundleNavigationAction.h"
36 #include "NavigationActionData.h"
37 #include "PluginView.h"
38 #include "UserData.h"
39 #include "WKBundleAPICast.h"
40 #include "WebAutomationSessionProxy.h"
41 #include "WebBackForwardListProxy.h"
42 #include "WebCoreArgumentCoders.h"
43 #include "WebDocumentLoader.h"
44 #include "WebErrors.h"
45 #include "WebEvent.h"
46 #include "WebFrame.h"
47 #include "WebFrameNetworkingContext.h"
48 #include "WebFullScreenManager.h"
49 #include "WebIconDatabaseMessages.h"
50 #include "WebNavigationDataStore.h"
51 #include "WebPage.h"
52 #include "WebPageGroupProxy.h"
53 #include "WebPageProxyMessages.h"
54 #include "WebProcess.h"
55 #include "WebProcessPoolMessages.h"
56 #include "WebsitePolicies.h"
57 #include <JavaScriptCore/APICast.h>
58 #include <JavaScriptCore/JSObject.h>
59 #include <WebCore/CachedFrame.h>
60 #include <WebCore/CertificateInfo.h>
61 #include <WebCore/Chrome.h>
62 #include <WebCore/DOMWrapperWorld.h>
63 #include <WebCore/DocumentLoader.h>
64 #include <WebCore/FormState.h>
65 #include <WebCore/FrameLoadRequest.h>
66 #include <WebCore/FrameLoader.h>
67 #include <WebCore/FrameView.h>
68 #include <WebCore/HTMLAppletElement.h>
69 #include <WebCore/HTMLFormElement.h>
70 #include <WebCore/HistoryController.h>
71 #include <WebCore/HistoryItem.h>
72 #include <WebCore/MIMETypeRegistry.h>
73 #include <WebCore/MainFrame.h>
74 #include <WebCore/MouseEvent.h>
75 #include <WebCore/NotImplemented.h>
76 #include <WebCore/Page.h>
77 #include <WebCore/PluginData.h>
78 #include <WebCore/PluginDocument.h>
79 #include <WebCore/ProgressTracker.h>
80 #include <WebCore/ResourceError.h>
81 #include <WebCore/ScriptController.h>
82 #include <WebCore/SecurityOriginData.h>
83 #include <WebCore/Settings.h>
84 #include <WebCore/SubframeLoader.h>
85 #include <WebCore/UIEventWithKeyState.h>
86 #include <WebCore/Widget.h>
87 #include <WebCore/WindowFeatures.h>
88 #include <wtf/NeverDestroyed.h>
89
90 using namespace WebCore;
91
92 namespace WebKit {
93
94 WebFrameLoaderClient::WebFrameLoaderClient()
95     : m_frame(0)
96     , m_hasSentResponseToPluginView(false)
97     , m_didCompletePageTransition(false)
98     , m_frameHasCustomContentProvider(false)
99     , m_frameCameFromPageCache(false)
100 {
101 }
102
103 WebFrameLoaderClient::~WebFrameLoaderClient()
104 {
105 }
106     
107 void WebFrameLoaderClient::frameLoaderDestroyed()
108 {
109     m_frame->invalidate();
110
111     // Balances explicit ref() in WebFrame::create().
112     m_frame->deref();
113 }
114
115 bool WebFrameLoaderClient::hasHTMLView() const
116 {
117     return !m_frameHasCustomContentProvider;
118 }
119
120 bool WebFrameLoaderClient::hasWebView() const
121 {
122     return m_frame->page();
123 }
124
125 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*)
126 {
127     notImplemented();
128 }
129
130 void WebFrameLoaderClient::forceLayoutForNonHTML()
131 {
132     notImplemented();
133 }
134
135 void WebFrameLoaderClient::setCopiesOnScroll()
136 {
137     notImplemented();
138 }
139
140 void WebFrameLoaderClient::detachedFromParent2()
141 {
142     WebPage* webPage = m_frame->page();
143     if (!webPage)
144         return;
145
146     RefPtr<API::Object> userData;
147
148     // Notify the bundle client.
149     webPage->injectedBundleLoaderClient().didRemoveFrameFromHierarchy(webPage, m_frame, userData);
150 }
151
152 void WebFrameLoaderClient::detachedFromParent3()
153 {
154     notImplemented();
155 }
156
157 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
158 {
159     WebPage* webPage = m_frame->page();
160     if (!webPage)
161         return;
162
163     bool pageIsProvisionallyLoading = false;
164     if (FrameLoader* frameLoader = loader->frameLoader())
165         pageIsProvisionallyLoading = frameLoader->provisionalDocumentLoader() == loader;
166
167     webPage->injectedBundleResourceLoadClient().didInitiateLoadForResource(webPage, m_frame, identifier, request, pageIsProvisionallyLoading);
168     webPage->addResourceRequest(identifier, request);
169 }
170
171 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
172 {
173     WebPage* webPage = m_frame->page();
174     if (!webPage)
175         return;
176
177     webPage->injectedBundleResourceLoadClient().willSendRequestForFrame(webPage, m_frame, identifier, request, redirectResponse);
178 }
179
180 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier)
181 {
182     WebPage* webPage = m_frame->page();
183     if (!webPage)
184         return true;
185
186     return webPage->injectedBundleResourceLoadClient().shouldUseCredentialStorage(webPage, m_frame, identifier);
187 }
188
189 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge)
190 {
191     // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
192     // Once we do, we might need to make sure authentication fits with our solution.
193
194     WebPage* webPage = m_frame->page();
195     if (!webPage)
196         return;
197
198     WebProcess::singleton().supplement<AuthenticationManager>()->didReceiveAuthenticationChallenge(m_frame, challenge);
199 }
200
201 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
202 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader*, unsigned long, const ProtectionSpace& protectionSpace)
203 {
204     // The WebKit 2 Networking process asks the UIProcess directly, so the WebContent process should never receive this callback.
205     ASSERT_NOT_REACHED();
206     return false;
207 }
208 #endif
209
210 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response)
211 {
212     WebPage* webPage = m_frame->page();
213     if (!webPage)
214         return;
215
216     webPage->injectedBundleResourceLoadClient().didReceiveResponseForResource(webPage, m_frame, identifier, response);
217 }
218
219 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength)
220 {
221     WebPage* webPage = m_frame->page();
222     if (!webPage)
223         return;
224
225     webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(webPage, m_frame, identifier, dataLength);
226 }
227
228 #if ENABLE(DATA_DETECTION)
229 void WebFrameLoaderClient::dispatchDidFinishDataDetection(NSArray *detectionResults)
230 {
231     WebPage* webPage = m_frame->page();
232     if (!webPage)
233         return;
234     webPage->setDataDetectionResults(detectionResults);
235 }
236 #endif
237
238 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier)
239 {
240     WebPage* webPage = m_frame->page();
241     if (!webPage)
242         return;
243
244     webPage->injectedBundleResourceLoadClient().didFinishLoadForResource(webPage, m_frame, identifier);
245     webPage->removeResourceRequest(identifier);
246 }
247
248 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& error)
249 {
250     WebPage* webPage = m_frame->page();
251     if (!webPage)
252         return;
253
254     webPage->injectedBundleResourceLoadClient().didFailLoadForResource(webPage, m_frame, identifier, error);
255     webPage->removeResourceRequest(identifier);
256 }
257
258 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
259 {
260     notImplemented();
261     return false;
262 }
263
264 void WebFrameLoaderClient::dispatchDidDispatchOnloadEvents()
265 {
266     WebPage* webPage = m_frame->page();
267     if (!webPage)
268         return;
269
270     // Notify the bundle client.
271     webPage->injectedBundleLoaderClient().didHandleOnloadEventsForFrame(webPage, m_frame);
272 }
273
274 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
275 {
276     WebPage* webPage = m_frame->page();
277     if (!webPage)
278         return;
279
280     WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader());
281     const String& url = documentLoader.url().string();
282     RefPtr<API::Object> userData;
283
284     // Notify the bundle client.
285     webPage->injectedBundleLoaderClient().didReceiveServerRedirectForProvisionalLoadForFrame(webPage, m_frame, userData);
286
287     // Notify the UIProcess.
288     webPage->send(Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame(m_frame->frameID(), documentLoader.navigationID(), url, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
289 }
290
291 void WebFrameLoaderClient::dispatchDidChangeProvisionalURL()
292 {
293     WebPage* webPage = m_frame->page();
294     if (!webPage)
295         return;
296
297     WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader());
298     webPage->send(Messages::WebPageProxy::DidChangeProvisionalURLForFrame(m_frame->frameID(), documentLoader.navigationID(), documentLoader.url().string()));
299 }
300
301 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
302 {
303     WebPage* webPage = m_frame->page();
304     if (!webPage)
305         return;
306
307     // Notify the bundle client.
308     webPage->injectedBundleLoaderClient().didCancelClientRedirectForFrame(webPage, m_frame);
309 }
310
311 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const URL& url, double interval, double fireDate)
312 {
313     WebPage* webPage = m_frame->page();
314     if (!webPage)
315         return;
316
317     // Notify the bundle client.
318     webPage->injectedBundleLoaderClient().willPerformClientRedirectForFrame(webPage, m_frame, url.string(), interval, fireDate);
319 }
320
321 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
322 {
323     WebPage* webPage = m_frame->page();
324     if (!webPage)
325         return;
326
327     RefPtr<API::Object> userData;
328
329     auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
330
331     // Notify the bundle client.
332     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationAnchorNavigation, userData);
333
334     // Notify the UIProcess.
335     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationAnchorNavigation, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
336 }
337
338 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
339 {
340     WebPage* webPage = m_frame->page();
341     if (!webPage)
342         return;
343
344     RefPtr<API::Object> userData;
345
346     auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
347
348     // Notify the bundle client.
349     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePush, userData);
350
351     // Notify the UIProcess.
352     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationSessionStatePush, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
353 }
354
355 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
356 {
357     WebPage* webPage = m_frame->page();
358     if (!webPage)
359         return;
360
361     RefPtr<API::Object> userData;
362
363     auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
364
365     // Notify the bundle client.
366     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStateReplace, userData);
367
368     // Notify the UIProcess.
369     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationSessionStateReplace, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
370 }
371
372 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
373 {
374     WebPage* webPage = m_frame->page();
375     if (!webPage)
376         return;
377
378     RefPtr<API::Object> userData;
379
380     auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
381
382     // Notify the bundle client.
383     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePop, userData);
384
385     // Notify the UIProcess.
386     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationSessionStatePop, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
387 }
388
389 void WebFrameLoaderClient::dispatchWillClose()
390 {
391     notImplemented();
392 }
393
394 void WebFrameLoaderClient::dispatchDidReceiveIcon()
395 {
396     WebProcess::singleton().parentProcessConnection()->send(Messages::WebIconDatabase::DidReceiveIconForPageURL(m_frame->url()), 0);
397 }
398
399 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
400 {
401     WebPage* webPage = m_frame->page();
402     if (!webPage)
403         return;
404
405 #if ENABLE(FULLSCREEN_API)
406     Element* documentElement = m_frame->coreFrame()->document()->documentElement();
407     if (documentElement && documentElement->containsFullScreenElement())
408         webPage->fullScreenManager()->exitFullScreenForElement(webPage->fullScreenManager()->element());
409 #endif
410
411     webPage->findController().hideFindUI();
412     webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame);
413
414     WebDocumentLoader& provisionalLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader());
415     const String& url = provisionalLoader.url().string();
416     RefPtr<API::Object> userData;
417
418     // Notify the bundle client.
419     webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(webPage, m_frame, userData);
420
421     String unreachableURL = provisionalLoader.unreachableURL().string();
422
423     // Notify the UIProcess.
424     webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), provisionalLoader.navigationID(), url, unreachableURL, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
425 }
426
427 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
428 {
429     WebPage* webPage = m_frame->page();
430     if (!webPage)
431         return;
432
433     RefPtr<API::Object> userData;
434
435     // Notify the bundle client.
436     // FIXME: Use direction of title.
437     webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title.string, m_frame, userData);
438
439     // Notify the UIProcess.
440     webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title.string, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
441 }
442
443 void WebFrameLoaderClient::dispatchDidCommitLoad(std::optional<HasInsecureContent> hasInsecureContent)
444 {
445     WebPage* webPage = m_frame->page();
446     if (!webPage)
447         return;
448
449     WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader());
450     RefPtr<API::Object> userData;
451
452     // Notify the bundle client.
453     webPage->injectedBundleLoaderClient().didCommitLoadForFrame(webPage, m_frame, userData);
454
455     webPage->sandboxExtensionTracker().didCommitProvisionalLoad(m_frame);
456
457     // Notify the UIProcess.
458     webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), documentLoader.navigationID(), documentLoader.response().mimeType(), m_frameHasCustomContentProvider, static_cast<uint32_t>(m_frame->coreFrame()->loader().loadType()), valueOrCompute(documentLoader.response().certificateInfo(), [] { return CertificateInfo(); }), m_frame->coreFrame()->document()->isPluginDocument(), hasInsecureContent, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
459     webPage->didCommitLoad(m_frame);
460 }
461
462 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
463 {
464     WebPage* webPage = m_frame->page();
465     if (!webPage)
466         return;
467
468     RefPtr<API::Object> userData;
469
470     // Notify the bundle client.
471     webPage->injectedBundleLoaderClient().didFailProvisionalLoadWithErrorForFrame(webPage, m_frame, error, userData);
472
473     webPage->sandboxExtensionTracker().didFailProvisionalLoad(m_frame);
474
475     // FIXME: This is gross. This is necessary because if the client calls WKBundlePageStopLoading() from within the didFailProvisionalLoadWithErrorForFrame
476     // injected bundle client call, that will cause the provisional DocumentLoader to be disconnected from the Frame, and didDistroyNavigation message
477     // to be sent to the UIProcess (and the destruction of the DocumentLoader). If that happens, and we had captured the navigationID before injected bundle 
478     // client call, the DidFailProvisionalLoadForFrame would send a navigationID of a destroyed Navigation, and the UIProcess would not be able to find it
479     // in its table.
480     //
481     // A better solution to this problem would be find a clean way to postpone the disconnection of the DocumentLoader from the Frame until
482     // the entire FrameLoaderClient function was complete.
483     uint64_t navigationID = 0;
484     if (auto documentLoader = m_frame->coreFrame()->loader().provisionalDocumentLoader())
485         navigationID = static_cast<WebDocumentLoader*>(documentLoader)->navigationID();
486
487     // Notify the UIProcess.
488     WebCore::Frame* coreFrame = m_frame ? m_frame->coreFrame() : nullptr;
489     webPage->send(Messages::WebPageProxy::DidFailProvisionalLoadForFrame(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), navigationID, m_frame->coreFrame()->loader().provisionalLoadErrorBeingHandledURL(), error, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
490
491     // If we have a load listener, notify it.
492     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
493         loadListener->didFailLoad(m_frame, error.isCancellation());
494 }
495
496 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
497 {
498     WebPage* webPage = m_frame->page();
499     if (!webPage)
500         return;
501
502     RefPtr<API::Object> userData;
503
504     auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
505
506     // Notify the bundle client.
507     webPage->injectedBundleLoaderClient().didFailLoadWithErrorForFrame(webPage, m_frame, error, userData);
508
509     // Notify the UIProcess.
510     webPage->send(Messages::WebPageProxy::DidFailLoadForFrame(m_frame->frameID(), navigationID, error, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
511
512     // If we have a load listener, notify it.
513     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
514         loadListener->didFailLoad(m_frame, error.isCancellation());
515 }
516
517 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
518 {
519     WebPage* webPage = m_frame->page();
520     if (!webPage)
521         return;
522
523     RefPtr<API::Object> userData;
524
525     auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
526
527     // Notify the bundle client.
528     webPage->injectedBundleLoaderClient().didFinishDocumentLoadForFrame(webPage, m_frame, userData);
529
530     // Notify the UIProcess.
531     webPage->send(Messages::WebPageProxy::DidFinishDocumentLoadForFrame(m_frame->frameID(), navigationID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
532 }
533
534 void WebFrameLoaderClient::dispatchDidFinishLoad()
535 {
536     WebPage* webPage = m_frame->page();
537     if (!webPage)
538         return;
539
540     RefPtr<API::Object> userData;
541
542     auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
543
544     // Notify the bundle client.
545     webPage->injectedBundleLoaderClient().didFinishLoadForFrame(webPage, m_frame, userData);
546
547     // Notify the UIProcess.
548     webPage->send(Messages::WebPageProxy::DidFinishLoadForFrame(m_frame->frameID(), navigationID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
549
550     // If we have a load listener, notify it.
551     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
552         loadListener->didFinishLoad(m_frame);
553
554     webPage->didFinishLoad(m_frame);
555 }
556
557 void WebFrameLoaderClient::forcePageTransitionIfNeeded()
558 {
559     if (m_didCompletePageTransition)
560         return;
561
562     WebPage* webPage = m_frame->page();
563     if (!webPage)
564         return;
565
566     webPage->didCompletePageTransition();
567     m_didCompletePageTransition = true;
568 }
569
570 void WebFrameLoaderClient::dispatchDidReachLayoutMilestone(LayoutMilestones milestones)
571 {
572     WebPage* webPage = m_frame->page();
573     if (!webPage)
574         return;
575
576     RefPtr<API::Object> userData;
577
578     if (milestones & DidFirstLayout) {
579         // FIXME: We should consider removing the old didFirstLayout API since this is doing double duty with the
580         // new didLayout API.
581         webPage->injectedBundleLoaderClient().didFirstLayoutForFrame(webPage, m_frame, userData);
582         webPage->send(Messages::WebPageProxy::DidFirstLayoutForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
583
584 #if PLATFORM(MAC)
585         // FIXME: Do this on DidFirstVisuallyNonEmptyLayout when Mac Safari is able to handle it (<rdar://problem/17580021>)
586         if (m_frame->isMainFrame() && !m_didCompletePageTransition && !webPage->corePage()->settings().suppressesIncrementalRendering()) {
587             webPage->didCompletePageTransition();
588             m_didCompletePageTransition = true;
589         }
590 #endif
591
592 #if USE(COORDINATED_GRAPHICS)
593         // Make sure viewport properties are dispatched on the main frame by the time the first layout happens.
594         ASSERT(!webPage->useFixedLayout() || m_frame != m_frame->page()->mainWebFrame() || m_frame->coreFrame()->document()->didDispatchViewportPropertiesChanged());
595 #endif
596     }
597
598     // Send this after DidFirstLayout-specific calls since some clients expect to get those messages first.
599     webPage->dispatchDidReachLayoutMilestone(milestones);
600
601     if (milestones & DidFirstVisuallyNonEmptyLayout) {
602         if (m_frame->isMainFrame() && !m_didCompletePageTransition && !webPage->corePage()->settings().suppressesIncrementalRendering()) {
603             webPage->didCompletePageTransition();
604             m_didCompletePageTransition = true;
605         }
606
607         // FIXME: We should consider removing the old didFirstVisuallyNonEmptyLayoutForFrame API since this is doing
608         // double duty with the new didLayout API.
609         webPage->injectedBundleLoaderClient().didFirstVisuallyNonEmptyLayoutForFrame(webPage, m_frame, userData);
610         webPage->send(Messages::WebPageProxy::DidFirstVisuallyNonEmptyLayoutForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
611     }
612 }
613
614 void WebFrameLoaderClient::dispatchDidLayout()
615 {
616     WebPage* webPage = m_frame->page();
617     if (!webPage)
618         return;
619
620     // Notify the bundle client.
621     webPage->injectedBundleLoaderClient().didLayoutForFrame(webPage, m_frame);
622
623     webPage->recomputeShortCircuitHorizontalWheelEventsState();
624
625 #if PLATFORM(IOS)
626     webPage->updateSelectionAppearance();
627 #endif
628
629     // NOTE: Unlike the other layout notifications, this does not notify the
630     // the UIProcess for every call.
631
632     if (m_frame == m_frame->page()->mainWebFrame()) {
633         // FIXME: Remove at the soonest possible time.
634         webPage->send(Messages::WebPageProxy::SetRenderTreeSize(webPage->renderTreeSize()));
635         webPage->mainFrameDidLayout();
636     }
637 }
638
639 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction)
640 {
641     WebPage* webPage = m_frame->page();
642     if (!webPage)
643         return 0;
644
645     // Just call through to the chrome client.
646     FrameLoadRequest request(m_frame->coreFrame()->document()->securityOrigin(), navigationAction.resourceRequest(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, navigationAction.shouldOpenExternalURLsPolicy());
647     Page* newPage = webPage->corePage()->chrome().createWindow(m_frame->coreFrame(), request, WindowFeatures(), navigationAction);
648     if (!newPage)
649         return 0;
650     
651     return &newPage->mainFrame();
652 }
653
654 void WebFrameLoaderClient::dispatchShow()
655 {
656     WebPage* webPage = m_frame->page();
657     if (!webPage)
658         return;
659
660     webPage->show();
661 }
662
663 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, FramePolicyFunction function)
664 {
665     WebPage* webPage = m_frame->page();
666     if (!webPage) {
667         function(PolicyIgnore);
668         return;
669     }
670
671     if (!request.url().string()) {
672         function(PolicyUse);
673         return;
674     }
675
676     RefPtr<API::Object> userData;
677
678     // Notify the bundle client.
679     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForResponse(webPage, m_frame, response, request, userData);
680     if (policy == WKBundlePagePolicyActionUse) {
681         function(PolicyUse);
682         return;
683     }
684
685     bool canShowMIMEType = webPage->canShowMIMEType(response.mimeType());
686
687     uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
688     bool receivedPolicyAction;
689     uint64_t policyAction;
690     DownloadID downloadID;
691
692     Ref<WebFrame> protect(*m_frame);
693     WebCore::Frame* coreFrame = m_frame->coreFrame();
694     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponseSync(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), response, request, canShowMIMEType, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForResponseSync::Reply(receivedPolicyAction, policyAction, downloadID), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend)) {
695         m_frame->didReceivePolicyDecision(listenerID, PolicyIgnore, 0, { });
696         return;
697     }
698
699     // We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback.
700     if (receivedPolicyAction)
701         m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), 0, downloadID);
702 }
703
704 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const NavigationAction& navigationAction, const ResourceRequest& request, FormState* formState, const String& frameName, FramePolicyFunction function)
705 {
706     WebPage* webPage = m_frame->page();
707     if (!webPage) {
708         function(PolicyIgnore);
709         return;
710     }
711
712     RefPtr<API::Object> userData;
713
714     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
715
716     // Notify the bundle client.
717     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNewWindowAction(webPage, m_frame, action.get(), request, frameName, userData);
718     if (policy == WKBundlePagePolicyActionUse) {
719         function(PolicyUse);
720         return;
721     }
722
723
724     uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
725
726     NavigationActionData navigationActionData;
727     navigationActionData.navigationType = action->navigationType();
728     navigationActionData.modifiers = action->modifiers();
729     navigationActionData.mouseButton = action->mouseButton();
730     navigationActionData.syntheticClickType = action->syntheticClickType();
731     navigationActionData.userGestureTokenIdentifier = WebProcess::singleton().userGestureTokenIdentifier(navigationAction.userGestureToken());
732     navigationActionData.canHandleRequest = webPage->canHandleRequest(request);
733     navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
734     navigationActionData.downloadAttribute = navigationAction.downloadAttribute();
735
736     WebCore::Frame* coreFrame = m_frame ? m_frame->coreFrame() : nullptr;
737     webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), navigationActionData, request, frameName, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
738 }
739
740 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, FormState* formState, FramePolicyFunction function)
741 {
742     WebPage* webPage = m_frame->page();
743     if (!webPage) {
744         function(PolicyIgnore);
745         return;
746     }
747
748     // Always ignore requests with empty URLs. 
749     if (request.isEmpty()) {
750         function(PolicyIgnore);
751         return;
752     }
753
754     RefPtr<API::Object> userData;
755
756     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
757
758     // Notify the bundle client.
759     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.get(), request, userData);
760     if (policy == WKBundlePagePolicyActionUse) {
761         function(PolicyUse);
762         return;
763     }
764     
765     uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
766     bool receivedPolicyAction;
767     uint64_t newNavigationID;
768     uint64_t policyAction;
769     DownloadID downloadID;
770
771     RefPtr<WebFrame> originatingFrame;
772     switch (action->navigationType()) {
773     case NavigationType::LinkClicked:
774         if (EventTarget* target = navigationAction.event()->target()) {
775             if (Node* node = target->toNode()) {
776                 if (Frame* frame = node->document().frame())
777                     originatingFrame = WebFrame::fromCoreFrame(*frame);
778             }
779         }
780         break;
781     case NavigationType::FormSubmitted:
782     case NavigationType::FormResubmitted:
783         if (formState)
784             originatingFrame = WebFrame::fromCoreFrame(*formState->sourceDocument().frame());
785         break;
786     case NavigationType::BackForward:
787     case NavigationType::Reload:
788     case NavigationType::Other:
789         break;
790     }
791
792     NavigationActionData navigationActionData;
793     navigationActionData.navigationType = action->navigationType();
794     navigationActionData.modifiers = action->modifiers();
795     navigationActionData.mouseButton = action->mouseButton();
796     navigationActionData.syntheticClickType = action->syntheticClickType();
797     navigationActionData.userGestureTokenIdentifier = WebProcess::singleton().userGestureTokenIdentifier(navigationAction.userGestureToken());
798     navigationActionData.canHandleRequest = webPage->canHandleRequest(request);
799     navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
800     navigationActionData.downloadAttribute = navigationAction.downloadAttribute();
801
802     WebCore::Frame* coreFrame = m_frame->coreFrame();
803     WebDocumentLoader* documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().policyDocumentLoader());
804     if (!documentLoader)
805         documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().documentLoader());
806
807     // Notify the UIProcess.
808     Ref<WebFrame> protect(*m_frame);
809     WebCore::Frame* originatingCoreFrame = originatingFrame ? originatingFrame->coreFrame() : nullptr;
810     WebsitePolicies websitePolicies;
811     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), documentLoader->navigationID(), navigationActionData, originatingFrame ? originatingFrame->frameID() : 0, SecurityOriginData::fromFrame(originatingCoreFrame), navigationAction.resourceRequest(), request, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(receivedPolicyAction, newNavigationID, policyAction, downloadID, websitePolicies))) {
812         m_frame->didReceivePolicyDecision(listenerID, PolicyIgnore, 0, { });
813         return;
814     }
815
816     // Only setUserContentExtensionsEnabled if it hasn't already been disabled by reloading without content blockers.
817     if (documentLoader->userContentExtensionsEnabled())
818         documentLoader->setUserContentExtensionsEnabled(websitePolicies.contentBlockersEnabled);
819
820     // We call this synchronously because WebCore cannot gracefully handle a frame load without a synchronous navigation policy reply.
821     if (receivedPolicyAction)
822         m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), newNavigationID, downloadID);
823 }
824
825 void WebFrameLoaderClient::cancelPolicyCheck()
826 {
827     m_frame->invalidatePolicyListener();
828 }
829
830 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
831 {
832     WebPage* webPage = m_frame->page();
833     if (!webPage)
834         return;
835
836     RefPtr<API::Object> userData;
837
838     // Notify the bundle client.
839     webPage->injectedBundlePolicyClient().unableToImplementPolicy(webPage, m_frame, error, userData);
840
841     // Notify the UIProcess.
842     webPage->send(Messages::WebPageProxy::UnableToImplementPolicy(m_frame->frameID(), error, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
843 }
844
845 void WebFrameLoaderClient::dispatchWillSendSubmitEvent(Ref<FormState>&& formState)
846 {
847     auto* webPage = m_frame->page();
848     if (!webPage)
849         return;
850
851     auto& form = formState->form();
852
853     ASSERT(formState->sourceDocument().frame());
854     auto* sourceFrame = WebFrame::fromCoreFrame(*formState->sourceDocument().frame());
855     ASSERT(sourceFrame);
856
857     webPage->injectedBundleFormClient().willSendSubmitEvent(webPage, &form, m_frame, sourceFrame, formState->textFieldValues());
858 }
859
860 void WebFrameLoaderClient::dispatchWillSubmitForm(FormState& formState, FramePolicyFunction function)
861 {
862     WebPage* webPage = m_frame->page();
863     if (!webPage)
864         return;
865
866     auto& form = formState.form();
867
868     auto* sourceFrame = WebFrame::fromCoreFrame(*formState.sourceDocument().frame());
869     ASSERT(sourceFrame);
870
871     auto& values = formState.textFieldValues();
872
873     RefPtr<API::Object> userData;
874     webPage->injectedBundleFormClient().willSubmitForm(webPage, &form, m_frame, sourceFrame, values, userData);
875
876     uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
877
878     webPage->send(Messages::WebPageProxy::WillSubmitForm(m_frame->frameID(), sourceFrame->frameID(), values, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
879 }
880
881 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*)
882 {
883     notImplemented();
884 }
885
886 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
887 {
888     if (!m_pluginView)
889         return;
890     
891     m_pluginView->manualLoadDidFail(error);
892     m_pluginView = nullptr;
893     m_hasSentResponseToPluginView = false;
894 }
895
896 void WebFrameLoaderClient::setMainFrameDocumentReady(bool)
897 {
898     notImplemented();
899 }
900
901 void WebFrameLoaderClient::startDownload(const ResourceRequest& request, const String& suggestedName)
902 {
903     m_frame->startDownload(request, suggestedName);
904 }
905
906 void WebFrameLoaderClient::willChangeTitle(DocumentLoader*)
907 {
908     notImplemented();
909 }
910
911 void WebFrameLoaderClient::didChangeTitle(DocumentLoader*)
912 {
913     notImplemented();
914 }
915
916 void WebFrameLoaderClient::willReplaceMultipartContent()
917 {
918     WebPage* webPage = m_frame->page();
919     if (!webPage)
920         return;
921     webPage->willReplaceMultipartContent(*m_frame);
922 }
923
924 void WebFrameLoaderClient::didReplaceMultipartContent()
925 {
926     WebPage* webPage = m_frame->page();
927     if (!webPage)
928         return;
929     webPage->didReplaceMultipartContent(*m_frame);
930 }
931
932 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
933 {
934     if (!m_pluginView)
935         loader->commitData(data, length);
936
937     // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
938     // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
939     if (m_frame->coreFrame()->document()->isMediaDocument())
940         loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
941
942     // Calling commitData did not create the plug-in view.
943     if (!m_pluginView)
944         return;
945
946     if (!m_hasSentResponseToPluginView) {
947         m_pluginView->manualLoadDidReceiveResponse(loader->response());
948         // manualLoadDidReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
949         // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
950         // to null
951         if (!m_pluginView)
952             return;
953         m_hasSentResponseToPluginView = true;
954     }
955     m_pluginView->manualLoadDidReceiveData(data, length);
956 }
957
958 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
959 {
960     if (!m_pluginView) {
961         if (m_frameHasCustomContentProvider) {
962             WebPage* webPage = m_frame->page();
963             if (!webPage)
964                 return;
965
966             RefPtr<SharedBuffer> mainResourceData = loader->mainResourceData();
967             IPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(mainResourceData ? mainResourceData->data() : 0), mainResourceData ? mainResourceData->size() : 0);
968             webPage->send(Messages::WebPageProxy::DidFinishLoadingDataForCustomContentProvider(loader->response().suggestedFilename(), dataReference));
969         }
970
971         return;
972     }
973
974     // If we just received an empty response without any data, we won't have sent a response to the plug-in view.
975     // Make sure to do this before calling manualLoadDidFinishLoading.
976     if (!m_hasSentResponseToPluginView) {
977         m_pluginView->manualLoadDidReceiveResponse(loader->response());
978
979         // Protect against the above call nulling out the plug-in (by trying to cancel the load for example).
980         if (!m_pluginView)
981             return;
982     }
983
984     m_pluginView->manualLoadDidFinishLoading();
985     m_pluginView = nullptr;
986     m_hasSentResponseToPluginView = false;
987 }
988
989 void WebFrameLoaderClient::updateGlobalHistory()
990 {
991     WebPage* webPage = m_frame->page();
992     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
993         return;
994
995     DocumentLoader* loader = m_frame->coreFrame()->loader().documentLoader();
996
997     WebNavigationDataStore data;
998     data.url = loader->url().string();
999     // FIXME: Use direction of title.
1000     data.title = loader->title().string;
1001     data.originalRequest = loader->originalRequestCopy();
1002     data.response = loader->response();
1003
1004     webPage->send(Messages::WebPageProxy::DidNavigateWithNavigationData(data, m_frame->frameID()));
1005 }
1006
1007 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
1008 {
1009     WebPage* webPage = m_frame->page();
1010     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
1011         return;
1012
1013     DocumentLoader* loader = m_frame->coreFrame()->loader().documentLoader();
1014     ASSERT(loader->unreachableURL().isEmpty());
1015
1016     // Client redirect
1017     if (!loader->clientRedirectSourceForHistory().isNull()) {
1018         webPage->send(Messages::WebPageProxy::DidPerformClientRedirect(
1019             loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_frame->frameID()));
1020     }
1021
1022     // Server redirect
1023     if (!loader->serverRedirectSourceForHistory().isNull()) {
1024         webPage->send(Messages::WebPageProxy::DidPerformServerRedirect(
1025             loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_frame->frameID()));
1026     }
1027 }
1028
1029 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
1030 {
1031     WebPage* webPage = m_frame->page();
1032     if (!webPage)
1033         return false;
1034     
1035     uint64_t itemID = WebBackForwardListProxy::idForItem(item);
1036     if (!itemID) {
1037         // We should never be considering navigating to an item that is not actually in the back/forward list.
1038         ASSERT_NOT_REACHED();
1039         return false;
1040     }
1041
1042     RefPtr<InjectedBundleBackForwardListItem> bundleItem = InjectedBundleBackForwardListItem::create(item);
1043     RefPtr<API::Object> userData;
1044
1045     // Ask the bundle client first
1046     bool shouldGoToBackForwardListItem = webPage->injectedBundleLoaderClient().shouldGoToBackForwardListItem(webPage, bundleItem.get(), userData);
1047     if (!shouldGoToBackForwardListItem)
1048         return false;
1049
1050     webPage->send(Messages::WebPageProxy::WillGoToBackForwardListItem(itemID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
1051     return true;
1052 }
1053
1054 void WebFrameLoaderClient::didDisplayInsecureContent()
1055 {
1056     WebPage* webPage = m_frame->page();
1057     if (!webPage)
1058         return;
1059
1060     RefPtr<API::Object> userData;
1061
1062     webPage->injectedBundleLoaderClient().didDisplayInsecureContentForFrame(webPage, m_frame, userData);
1063
1064     webPage->send(Messages::WebPageProxy::DidDisplayInsecureContentForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
1065 }
1066
1067 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin*, const URL&)
1068 {
1069     WebPage* webPage = m_frame->page();
1070     if (!webPage)
1071         return;
1072
1073     RefPtr<API::Object> userData;
1074
1075     webPage->injectedBundleLoaderClient().didRunInsecureContentForFrame(webPage, m_frame, userData);
1076
1077     webPage->send(Messages::WebPageProxy::DidRunInsecureContentForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
1078 }
1079
1080 void WebFrameLoaderClient::didDetectXSS(const URL&, bool)
1081 {
1082     WebPage* webPage = m_frame->page();
1083     if (!webPage)
1084         return;
1085
1086     RefPtr<API::Object> userData;
1087
1088     webPage->injectedBundleLoaderClient().didDetectXSSForFrame(webPage, m_frame, userData);
1089
1090     webPage->send(Messages::WebPageProxy::DidDetectXSSForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
1091 }
1092
1093 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
1094 {
1095     return WebKit::cancelledError(request);
1096 }
1097
1098 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
1099 {
1100     return WebKit::blockedError(request);
1101 }
1102
1103 ResourceError WebFrameLoaderClient::blockedByContentBlockerError(const ResourceRequest& request)
1104 {
1105     return WebKit::blockedByContentBlockerError(request);
1106 }
1107
1108 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
1109 {
1110     return WebKit::cannotShowURLError(request);
1111 }
1112
1113 ResourceError WebFrameLoaderClient::interruptedForPolicyChangeError(const ResourceRequest& request)
1114 {
1115     return WebKit::interruptedForPolicyChangeError(request);
1116 }
1117
1118 #if ENABLE(CONTENT_FILTERING)
1119 ResourceError WebFrameLoaderClient::blockedByContentFilterError(const ResourceRequest& request)
1120 {
1121     return WebKit::blockedByContentFilterError(request);
1122 }
1123 #endif
1124
1125 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
1126 {
1127     return WebKit::cannotShowMIMETypeError(response);
1128 }
1129
1130 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
1131 {
1132     return WebKit::fileDoesNotExistError(response);
1133 }
1134
1135 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
1136 {
1137     return WebKit::pluginWillHandleLoadError(response);
1138 }
1139
1140 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
1141 {
1142     static NeverDestroyed<const ResourceError> cancelledError(this->cancelledError(ResourceRequest()));
1143     static NeverDestroyed<const ResourceError> pluginWillHandleLoadError(this->pluginWillHandleLoadError(ResourceResponse()));
1144
1145     if (error.errorCode() == cancelledError.get().errorCode() && error.domain() == cancelledError.get().domain())
1146         return false;
1147
1148     if (error.errorCode() == pluginWillHandleLoadError.get().errorCode() && error.domain() == pluginWillHandleLoadError.get().domain())
1149         return false;
1150
1151     return true;
1152 }
1153
1154 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest&) const
1155 {
1156     notImplemented();
1157     return true;
1158 }
1159
1160 bool WebFrameLoaderClient::canShowMIMEType(const String& /*MIMEType*/) const
1161 {
1162     notImplemented();
1163     return true;
1164 }
1165
1166 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& /*MIMEType*/) const
1167 {
1168     return true;
1169 }
1170
1171 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& /*URLScheme*/) const
1172 {
1173     notImplemented();
1174     return false;
1175 }
1176
1177 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const
1178 {
1179     notImplemented();
1180     return String();
1181 }
1182
1183 void WebFrameLoaderClient::frameLoadCompleted()
1184 {
1185     // Note: Can be called multiple times.
1186     WebPage* webPage = m_frame->page();
1187     if (!webPage)
1188         return;
1189
1190     if (m_frame->isMainFrame() && !m_didCompletePageTransition) {
1191         webPage->didCompletePageTransition();
1192         m_didCompletePageTransition = true;
1193     }
1194 }
1195
1196 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem& historyItem)
1197 {
1198 #if PLATFORM(IOS) || PLATFORM(EFL)
1199     if (m_frame->isMainFrame())
1200         m_frame->page()->savePageState(historyItem);
1201 #else
1202     UNUSED_PARAM(historyItem);
1203 #endif
1204 }
1205
1206 void WebFrameLoaderClient::restoreViewState()
1207 {
1208 #if PLATFORM(IOS) || PLATFORM(EFL)
1209     Frame& frame = *m_frame->coreFrame();
1210     HistoryItem* currentItem = frame.loader().history().currentItem();
1211     if (FrameView* view = frame.view()) {
1212         if (m_frame->isMainFrame())
1213             m_frame->page()->restorePageState(*currentItem);
1214         else if (!view->wasScrolledByUser())
1215             view->setScrollPosition(currentItem->scrollPosition());
1216     }
1217 #else
1218     // Inform the UI process of the scale factor.
1219     double scaleFactor = m_frame->coreFrame()->loader().history().currentItem()->pageScaleFactor();
1220
1221     // A scale factor of 0 means the history item has the default scale factor, thus we do not need to update it.
1222     if (scaleFactor)
1223         m_frame->page()->send(Messages::WebPageProxy::PageScaleFactorDidChange(scaleFactor));
1224
1225     // FIXME: This should not be necessary. WebCore should be correctly invalidating
1226     // the view on restores from the back/forward cache.
1227     if (m_frame->page() && m_frame == m_frame->page()->mainWebFrame())
1228         m_frame->page()->drawingArea()->setNeedsDisplay();
1229 #endif
1230 }
1231
1232 void WebFrameLoaderClient::provisionalLoadStarted()
1233 {
1234     WebPage* webPage = m_frame->page();
1235     if (!webPage)
1236         return;
1237
1238     if (m_frame->isMainFrame()) {
1239         webPage->didStartPageTransition();
1240         m_didCompletePageTransition = false;
1241     }
1242 }
1243
1244 void WebFrameLoaderClient::didFinishLoad()
1245 {
1246     // If we have a load listener, notify it.
1247     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
1248         loadListener->didFinishLoad(m_frame);
1249 }
1250
1251 void WebFrameLoaderClient::prepareForDataSourceReplacement()
1252 {
1253     notImplemented();
1254 }
1255
1256 Ref<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
1257 {
1258     return m_frame->page()->createDocumentLoader(*m_frame->coreFrame(), request, substituteData);
1259 }
1260
1261 void WebFrameLoaderClient::updateCachedDocumentLoader(WebCore::DocumentLoader& loader)
1262 {
1263     m_frame->page()->updateCachedDocumentLoader(static_cast<WebDocumentLoader&>(loader), *m_frame->coreFrame());
1264 }
1265
1266 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const URL& url)
1267 {
1268     WebPage* webPage = m_frame->page();
1269     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
1270         return;
1271
1272     // FIXME: Use direction of title.
1273     webPage->send(Messages::WebPageProxy::DidUpdateHistoryTitle(title.string, url.string(), m_frame->frameID()));
1274 }
1275
1276 String WebFrameLoaderClient::userAgent(const URL& url)
1277 {
1278     WebPage* webPage = m_frame->page();
1279     if (!webPage)
1280         return String();
1281
1282     return webPage->userAgent(m_frame, url);
1283 }
1284
1285 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
1286 {
1287     WebPage* webPage = m_frame->page();
1288     if (!webPage)
1289         return;
1290
1291     HasInsecureContent hasInsecureContent;
1292     if (webPage->sendSync(Messages::WebPageProxy::HasInsecureContent(), Messages::WebPageProxy::HasInsecureContent::Reply(hasInsecureContent)))
1293         cachedFrame->setHasInsecureContent(hasInsecureContent);
1294 }
1295
1296 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
1297 {
1298     const ResourceResponse& response = m_frame->coreFrame()->loader().documentLoader()->response();
1299     m_frameHasCustomContentProvider = m_frame->isMainFrame() && m_frame->page()->shouldUseCustomContentProviderForResponse(response);
1300     m_frameCameFromPageCache = true;
1301 }
1302
1303 void WebFrameLoaderClient::transitionToCommittedForNewPage()
1304 {
1305     WebPage* webPage = m_frame->page();
1306
1307     Color backgroundColor = webPage->drawsBackground() ? Color::white : Color::transparent;
1308     bool isMainFrame = m_frame->isMainFrame();
1309     bool isTransparent = !webPage->drawsBackground();
1310     bool shouldUseFixedLayout = isMainFrame && webPage->useFixedLayout();
1311     bool shouldDisableScrolling = isMainFrame && !webPage->mainFrameIsScrollable();
1312     bool shouldHideScrollbars = shouldDisableScrolling;
1313     IntRect fixedVisibleContentRect;
1314
1315 #if USE(COORDINATED_GRAPHICS)
1316     if (m_frame->coreFrame()->view())
1317         fixedVisibleContentRect = m_frame->coreFrame()->view()->fixedVisibleContentRect();
1318     if (shouldUseFixedLayout)
1319         shouldHideScrollbars = true;
1320 #endif
1321
1322     const ResourceResponse& response = m_frame->coreFrame()->loader().documentLoader()->response();
1323     m_frameHasCustomContentProvider = isMainFrame && webPage->shouldUseCustomContentProviderForResponse(response);
1324     m_frameCameFromPageCache = false;
1325
1326     ScrollbarMode defaultScrollbarMode = shouldHideScrollbars ? ScrollbarAlwaysOff : ScrollbarAuto;
1327
1328     m_frame->coreFrame()->createView(webPage->size(), backgroundColor, isTransparent,
1329         webPage->fixedLayoutSize(), fixedVisibleContentRect, shouldUseFixedLayout,
1330         defaultScrollbarMode, /* lock */ shouldHideScrollbars, defaultScrollbarMode, /* lock */ shouldHideScrollbars);
1331
1332     if (int minimumLayoutWidth = webPage->minimumLayoutSize().width()) {
1333         int minimumLayoutHeight = std::max(webPage->minimumLayoutSize().height(), 1);
1334         int maximumSize = std::numeric_limits<int>::max();
1335         m_frame->coreFrame()->view()->enableAutoSizeMode(true, IntSize(minimumLayoutWidth, minimumLayoutHeight), IntSize(maximumSize, maximumSize));
1336
1337         if (webPage->autoSizingShouldExpandToViewHeight())
1338             m_frame->coreFrame()->view()->setAutoSizeFixedMinimumHeight(webPage->size().height());
1339     }
1340
1341     m_frame->coreFrame()->view()->setProhibitsScrolling(shouldDisableScrolling);
1342     m_frame->coreFrame()->view()->setVisualUpdatesAllowedByClient(!webPage->shouldExtendIncrementalRenderingSuppression());
1343 #if PLATFORM(COCOA)
1344     m_frame->coreFrame()->view()->setViewExposedRect(webPage->drawingArea()->viewExposedRect());
1345 #endif
1346 #if PLATFORM(IOS)
1347     m_frame->coreFrame()->view()->setDelegatesScrolling(true);
1348 #endif
1349
1350     if (webPage->scrollPinningBehavior() != DoNotPin)
1351         m_frame->coreFrame()->view()->setScrollPinningBehavior(webPage->scrollPinningBehavior());
1352
1353 #if USE(COORDINATED_GRAPHICS)
1354     if (shouldUseFixedLayout) {
1355         m_frame->coreFrame()->view()->setDelegatesScrolling(shouldUseFixedLayout);
1356         m_frame->coreFrame()->view()->setPaintsEntireContents(shouldUseFixedLayout);
1357         return;
1358     }
1359 #endif
1360 }
1361
1362 void WebFrameLoaderClient::didSaveToPageCache()
1363 {
1364     WebPage* webPage = m_frame->page();
1365     if (!webPage)
1366         return;
1367
1368     if (m_frame->isMainFrame())
1369         webPage->send(Messages::WebPageProxy::DidSaveToPageCache());
1370 }
1371
1372 void WebFrameLoaderClient::didRestoreFromPageCache()
1373 {
1374     m_frameCameFromPageCache = true;
1375 }
1376
1377 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool value)
1378 {
1379     WebPage* webPage = m_frame->page();
1380     if (!webPage)
1381         return;
1382
1383     webPage->send(Messages::WebPageProxy::FrameDidBecomeFrameSet(m_frame->frameID(), value));
1384 }
1385
1386 bool WebFrameLoaderClient::canCachePage() const
1387 {
1388     // We cannot cache frames that have custom representations because they are
1389     // rendered in the UIProcess.
1390     return !m_frameHasCustomContentProvider;
1391 }
1392
1393 void WebFrameLoaderClient::convertMainResourceLoadToDownload(DocumentLoader *documentLoader, SessionID sessionID, const ResourceRequest& request, const ResourceResponse& response)
1394 {
1395     m_frame->convertMainResourceLoadToDownload(documentLoader, sessionID, request, response);
1396 }
1397
1398 RefPtr<Frame> WebFrameLoaderClient::createFrame(const URL& url, const String& name, HTMLFrameOwnerElement& ownerElement,
1399     const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
1400 {
1401     auto* webPage = m_frame->page();
1402
1403     auto subframe = WebFrame::createSubframe(webPage, name, &ownerElement);
1404     auto* coreSubframe = subframe->coreFrame();
1405     if (!coreSubframe)
1406         return nullptr;
1407
1408     // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1409     if (!coreSubframe->page())
1410         return nullptr;
1411
1412     m_frame->coreFrame()->loader().loadURLIntoChildFrame(url, referrer, coreSubframe);
1413
1414     // The frame's onload handler may have removed it from the document.
1415     if (!subframe->coreFrame())
1416         return nullptr;
1417     ASSERT(subframe->coreFrame() == coreSubframe);
1418     if (!coreSubframe->tree().parent())
1419         return nullptr;
1420
1421     return coreSubframe;
1422 }
1423
1424 RefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement& pluginElement, const URL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1425 {
1426     ASSERT(paramNames.size() == paramValues.size());
1427     ASSERT(m_frame->page());
1428
1429     Plugin::Parameters parameters;
1430     parameters.url = url;
1431     parameters.names = paramNames;
1432     parameters.values = paramValues;
1433     parameters.mimeType = mimeType;
1434     parameters.isFullFramePlugin = loadManually;
1435     parameters.shouldUseManualLoader = parameters.isFullFramePlugin && !m_frameCameFromPageCache;
1436 #if PLATFORM(COCOA)
1437     parameters.layerHostingMode = m_frame->page()->layerHostingMode();
1438 #endif
1439
1440 #if ENABLE(NETSCAPE_PLUGIN_API)
1441     auto plugin = m_frame->page()->createPlugin(m_frame, &pluginElement, parameters, parameters.mimeType);
1442     if (!plugin)
1443         return nullptr;
1444
1445     return PluginView::create(pluginElement, plugin.releaseNonNull(), parameters);
1446 #else
1447     UNUSED_PARAM(pluginElement);
1448     return nullptr;
1449 #endif
1450 }
1451
1452 void WebFrameLoaderClient::recreatePlugin(Widget* widget)
1453 {
1454 #if ENABLE(NETSCAPE_PLUGIN_API)
1455     ASSERT(widget);
1456     ASSERT(widget->isPluginViewBase());
1457     ASSERT(m_frame->page());
1458
1459     auto& pluginView = static_cast<PluginView&>(*widget);
1460     String newMIMEType;
1461     auto plugin = m_frame->page()->createPlugin(m_frame, pluginView.pluginElement(), pluginView.initialParameters(), newMIMEType);
1462     pluginView.recreateAndInitialize(plugin.releaseNonNull());
1463 #else
1464     UNUSED_PARAM(widget);
1465 #endif
1466 }
1467
1468 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1469 {
1470     if (pluginWidget)
1471         m_pluginView = static_cast<PluginView*>(pluginWidget);
1472 }
1473
1474 #if ENABLE(WEBGL)
1475
1476 WebCore::WebGLLoadPolicy WebFrameLoaderClient::webGLPolicyForURL(const String& url) const
1477 {
1478     if (auto* webPage = m_frame->page())
1479         return webPage->webGLPolicyForURL(m_frame, url);
1480
1481     return WebGLAllowCreation;
1482 }
1483
1484 WebCore::WebGLLoadPolicy WebFrameLoaderClient::resolveWebGLPolicyForURL(const String& url) const
1485 {
1486     if (auto* webPage = m_frame->page())
1487         return webPage->resolveWebGLPolicyForURL(m_frame, url);
1488
1489     return WebGLAllowCreation;
1490 }
1491
1492 #endif
1493
1494 RefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement& appletElement, const URL&, const Vector<String>& paramNames, const Vector<String>& paramValues)
1495 {
1496 #if ENABLE(NETSCAPE_PLUGIN_API)
1497     auto plugin = createPlugin(pluginSize, appletElement, URL(), paramNames, paramValues, appletElement.serviceType(), false);
1498     if (!plugin) {
1499         if (auto* webPage = m_frame->page()) {
1500             auto frameURLString = m_frame->coreFrame()->loader().documentLoader()->responseURL().string();
1501             auto pageURLString = webPage->corePage()->mainFrame().loader().documentLoader()->responseURL().string();
1502             webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(appletElement.serviceType(), frameURLString, pageURLString));
1503         }
1504     }
1505     return plugin;
1506 #else
1507     UNUSED_PARAM(pluginSize);
1508     UNUSED_PARAM(appletElement);
1509     UNUSED_PARAM(paramNames);
1510     UNUSED_PARAM(paramValues);
1511     return nullptr;
1512 #endif
1513 }
1514
1515 static bool pluginSupportsExtension(const PluginData& pluginData, const String& extension)
1516 {
1517     ASSERT(extension.convertToASCIILowercase() == extension);
1518     Vector<MimeClassInfo> mimes;
1519     Vector<size_t> mimePluginIndices;
1520     pluginData.getWebVisibleMimesAndPluginIndices(mimes, mimePluginIndices);
1521     for (auto& mimeClassInfo : mimes) {
1522         if (mimeClassInfo.extensions.contains(extension))
1523             return true;
1524     }
1525     return false;
1526 }
1527
1528 ObjectContentType WebFrameLoaderClient::objectContentType(const URL& url, const String& mimeTypeIn)
1529 {
1530     // FIXME: This should eventually be merged with WebCore::FrameLoader::defaultObjectContentType.
1531
1532     String mimeType = mimeTypeIn;
1533     if (mimeType.isEmpty()) {
1534         String path = url.path();
1535         auto dotPosition = path.reverseFind('.');
1536         if (dotPosition == notFound)
1537             return ObjectContentType::Frame;
1538         String extension = path.substring(dotPosition + 1).convertToASCIILowercase();
1539
1540         // Try to guess the MIME type from the extension.
1541         mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
1542         if (mimeType.isEmpty()) {
1543             // Check if there's a plug-in around that can handle the extension.
1544             if (WebPage* webPage = m_frame->page()) {
1545                 if (pluginSupportsExtension(webPage->corePage()->pluginData(), extension))
1546                     return ObjectContentType::PlugIn;
1547             }
1548             return ObjectContentType::Frame;
1549         }
1550     }
1551
1552     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1553         return ObjectContentType::Image;
1554
1555     if (WebPage* webPage = m_frame->page()) {
1556         auto allowedPluginTypes = webFrame()->coreFrame()->loader().subframeLoader().allowPlugins()
1557             ? PluginData::AllPlugins : PluginData::OnlyApplicationPlugins;
1558         if (webPage->corePage()->pluginData().supportsMimeType(mimeType, allowedPluginTypes))
1559             return ObjectContentType::PlugIn;
1560     }
1561
1562     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1563         return ObjectContentType::Frame;
1564
1565 #if PLATFORM(IOS)
1566     // iOS can render PDF in <object>/<embed> via PDFDocumentImage.
1567     if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType))
1568         return ObjectContentType::Image;
1569 #endif
1570
1571     return ObjectContentType::None;
1572 }
1573
1574 String WebFrameLoaderClient::overrideMediaType() const
1575 {
1576     notImplemented();
1577     return String();
1578 }
1579
1580 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
1581 {
1582     WebPage* webPage = m_frame->page();
1583     if (!webPage)
1584         return;
1585
1586     webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(webPage, m_frame, world);
1587
1588
1589     WebAutomationSessionProxy* automationSessionProxy = WebProcess::singleton().automationSessionProxy();
1590     if (automationSessionProxy && world.isNormal())
1591         automationSessionProxy->didClearWindowObjectForFrame(*m_frame);
1592
1593 #if HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
1594     // Ensure the accessibility hierarchy is updated.
1595     webPage->updateAccessibilityTree();
1596 #endif
1597 }
1598
1599
1600 void WebFrameLoaderClient::dispatchGlobalObjectAvailable(DOMWrapperWorld& world)
1601 {
1602     WebPage* webPage = m_frame->page();
1603     if (!webPage)
1604         return;
1605     
1606     webPage->injectedBundleLoaderClient().globalObjectIsAvailableForFrame(webPage, m_frame, world);
1607 }
1608
1609 void WebFrameLoaderClient::dispatchWillDisconnectDOMWindowExtensionFromGlobalObject(WebCore::DOMWindowExtension* extension)
1610 {
1611     WebPage* webPage = m_frame->page();
1612     if (!webPage)
1613         return;
1614         
1615     webPage->injectedBundleLoaderClient().willDisconnectDOMWindowExtensionFromGlobalObject(webPage, extension);
1616 }
1617
1618 void WebFrameLoaderClient::dispatchDidReconnectDOMWindowExtensionToGlobalObject(WebCore::DOMWindowExtension* extension)
1619 {
1620     WebPage* webPage = m_frame->page();
1621     if (!webPage)
1622         return;
1623         
1624     webPage->injectedBundleLoaderClient().didReconnectDOMWindowExtensionToGlobalObject(webPage, extension);
1625 }
1626
1627 void WebFrameLoaderClient::dispatchWillDestroyGlobalObjectForDOMWindowExtension(WebCore::DOMWindowExtension* extension)
1628 {
1629     WebPage* webPage = m_frame->page();
1630     if (!webPage)
1631         return;
1632         
1633     webPage->injectedBundleLoaderClient().willDestroyGlobalObjectForDOMWindowExtension(webPage, extension);
1634 }
1635
1636 void WebFrameLoaderClient::registerForIconNotification(bool /*listen*/)
1637 {
1638     notImplemented();
1639 }
1640
1641 #if PLATFORM(COCOA)
1642     
1643 RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject() 
1644 {
1645     WebPage* webPage = m_frame->page();
1646     if (!webPage)
1647         return 0;
1648     
1649     return webPage->accessibilityRemoteObject();
1650 }
1651     
1652 NSCachedURLResponse *WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const
1653 {
1654     WebPage* webPage = m_frame->page();
1655     if (!webPage)
1656         return response;
1657
1658     return webPage->injectedBundleResourceLoadClient().shouldCacheResponse(webPage, m_frame, identifier) ? response : nil;
1659 }
1660
1661 NSDictionary *WebFrameLoaderClient::dataDetectionContext()
1662 {
1663     WebPage* webPage = m_frame->page();
1664     if (!webPage)
1665         return nil;
1666
1667     return webPage->dataDetectionContext();
1668 }
1669
1670 #endif // PLATFORM(COCOA)
1671
1672 bool WebFrameLoaderClient::shouldAlwaysUsePluginDocument(const String& /*mimeType*/) const
1673 {
1674     notImplemented();
1675     return false;
1676 }
1677
1678 void WebFrameLoaderClient::didChangeScrollOffset()
1679 {
1680     WebPage* webPage = m_frame->page();
1681     if (!webPage)
1682         return;
1683
1684     webPage->didChangeScrollOffsetForFrame(m_frame->coreFrame());
1685 }
1686
1687 bool WebFrameLoaderClient::allowScript(bool enabledPerSettings)
1688 {
1689     if (!enabledPerSettings)
1690         return false;
1691
1692     Frame* coreFrame = m_frame->coreFrame();
1693
1694     if (coreFrame->document()->isPluginDocument()) {
1695         PluginDocument* pluginDocument = static_cast<PluginDocument*>(coreFrame->document());
1696
1697         if (pluginDocument->pluginWidget() && pluginDocument->pluginWidget()->isPluginView()) {
1698             PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
1699
1700             if (!pluginView->shouldAllowScripting())
1701                 return false;
1702         }
1703     }
1704
1705     return true;
1706 }
1707
1708 bool WebFrameLoaderClient::shouldForceUniversalAccessFromLocalURL(const WebCore::URL& url)
1709 {
1710     WebPage* webPage = m_frame->page();
1711     if (!webPage)
1712         return false;
1713
1714     return webPage->injectedBundleLoaderClient().shouldForceUniversalAccessFromLocalURL(webPage, url.string());
1715 }
1716
1717 Ref<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1718 {
1719     return WebFrameNetworkingContext::create(m_frame);
1720 }
1721
1722 #if ENABLE(CONTENT_FILTERING)
1723
1724 void WebFrameLoaderClient::contentFilterDidBlockLoad(WebCore::ContentFilterUnblockHandler unblockHandler)
1725 {
1726     if (!unblockHandler.needsUIProcess()) {
1727         m_frame->coreFrame()->loader().policyChecker().setContentFilterUnblockHandler(WTFMove(unblockHandler));
1728         return;
1729     }
1730
1731     if (WebPage* webPage { m_frame->page() })
1732         webPage->send(Messages::WebPageProxy::ContentFilterDidBlockLoadForFrame(unblockHandler, m_frame->frameID()));
1733 }
1734
1735 #endif
1736
1737 #if ENABLE(REQUEST_AUTOCOMPLETE)
1738
1739 void WebFrameLoaderClient::didRequestAutocomplete(Ref<WebCore::FormState>&&)
1740 {
1741 }
1742
1743 #endif
1744
1745 void WebFrameLoaderClient::prefetchDNS(const String& hostname)
1746 {
1747     WebProcess::singleton().prefetchDNS(hostname);
1748 }
1749
1750 void WebFrameLoaderClient::didRestoreScrollPosition()
1751 {
1752     WebPage* webPage = m_frame->page();
1753     if (!webPage)
1754         return;
1755
1756     webPage->didRestoreScrollPosition();
1757 }
1758
1759 bool WebFrameLoaderClient::useIconLoadingClient()
1760 {
1761     return m_useIconLoadingClient;
1762 }
1763
1764 void WebFrameLoaderClient::getLoadDecisionForIcon(const LinkIcon& icon, uint64_t callbackID)
1765 {
1766     if (WebPage* webPage { m_frame->page() })
1767         webPage->send(Messages::WebPageProxy::GetLoadDecisionForIcon(icon, callbackID));
1768 }
1769
1770 void WebFrameLoaderClient::finishedLoadingIcon(uint64_t loadIdentifier, SharedBuffer* data)
1771 {
1772     if (WebPage* webPage { m_frame->page() }) {
1773         if (data)
1774             webPage->send(Messages::WebPageProxy::FinishedLoadingIcon(loadIdentifier, { reinterpret_cast<const uint8_t*>(data->data()), data->size() }));
1775         else
1776             webPage->send(Messages::WebPageProxy::FinishedLoadingIcon(loadIdentifier, { nullptr, 0 }));
1777     }
1778 }
1779
1780 } // namespace WebKit