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