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