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