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