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