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