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