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