Use OptionSet for layout milestones
[WebKit-https.git] / Source / WebKitLegacy / win / WebCoreSupport / WebFrameLoaderClient.cpp
1 /*
2  * Copyright (C) 2006-2017 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "WebFrameLoaderClient.h"
30
31 #include "CFDictionaryPropertyBag.h"
32 #include "COMPropertyBag.h"
33 #include "DOMHTMLClasses.h"
34 #include "DefaultPolicyDelegate.h"
35 #include "EmbeddedWidget.h"
36 #include "MarshallingHelpers.h"
37 #include "PluginDatabase.h"
38 #include "PluginPackage.h"
39 #include "PluginView.h"
40 #include "WebActionPropertyBag.h"
41 #include "WebCachedFramePlatformData.h"
42 #include "WebChromeClient.h"
43 #include "WebDocumentLoader.h"
44 #include "WebDownload.h"
45 #include "WebError.h"
46 #include "WebFrame.h"
47 #include "WebFrameNetworkingContext.h"
48 #include "WebFramePolicyListener.h"
49 #include "WebHistory.h"
50 #include "WebHistoryItem.h"
51 #include "WebMutableURLRequest.h"
52 #include "WebNavigationData.h"
53 #include "WebNotificationCenter.h"
54 #include "WebScriptWorld.h"
55 #include "WebSecurityOrigin.h"
56 #include "WebURLAuthenticationChallenge.h"
57 #include "WebURLResponse.h"
58 #include "WebView.h"
59 #include <JavaScriptCore/APICast.h>
60 #include <WebCore/BackForwardController.h>
61 #include <WebCore/CachedFrame.h>
62 #include <WebCore/DNS.h>
63 #include <WebCore/DocumentLoader.h>
64 #include <WebCore/FormState.h>
65 #include <WebCore/Frame.h>
66 #include <WebCore/FrameLoader.h>
67 #include <WebCore/FrameTree.h>
68 #include <WebCore/FrameView.h>
69 #include <WebCore/HTMLAppletElement.h>
70 #include <WebCore/HTMLFrameElement.h>
71 #include <WebCore/HTMLFrameOwnerElement.h>
72 #include <WebCore/HTMLNames.h>
73 #include <WebCore/HTMLParserIdioms.h>
74 #include <WebCore/HTMLPlugInElement.h>
75 #include <WebCore/HistoryItem.h>
76 #include <WebCore/LocalizedStrings.h>
77 #include <WebCore/MIMETypeRegistry.h>
78 #include <WebCore/NotImplemented.h>
79 #include <WebCore/Page.h>
80 #include <WebCore/PolicyChecker.h>
81 #include <WebCore/RenderWidget.h>
82 #include <WebCore/ResourceHandle.h>
83 #include <WebCore/ScriptController.h>
84 #include <WebCore/Settings.h>
85 #include <WebCore/SubresourceLoader.h>
86
87 using namespace WebCore;
88 using namespace HTMLNames;
89
90 static WebDataSource* getWebDataSource(DocumentLoader* loader)
91 {
92     return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0;
93 }
94
95 class WebFrameLoaderClient::WebFramePolicyListenerPrivate {
96 public:
97     WebFramePolicyListenerPrivate() 
98         : m_policyFunction(nullptr)
99     { 
100     }
101
102     ~WebFramePolicyListenerPrivate() { }
103
104     FramePolicyFunction m_policyFunction;
105     COMPtr<WebFramePolicyListener> m_policyListener;
106 };
107
108 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* webFrame)
109     : m_webFrame(webFrame)
110     , m_manualLoader(0)
111     , m_policyListenerPrivate(std::make_unique<WebFramePolicyListenerPrivate>())
112     , m_hasSentResponseToPlugin(false) 
113 {
114 }
115
116 WebFrameLoaderClient::~WebFrameLoaderClient()
117 {
118 }
119
120 void WebFrameLoaderClient::frameLoaderDestroyed()
121 {
122 }
123
124 std::optional<uint64_t> WebFrameLoaderClient::pageID() const
125 {
126     return std::nullopt;
127 }
128
129 std::optional<uint64_t> WebFrameLoaderClient::frameID() const
130 {
131     return std::nullopt;
132 }
133
134 PAL::SessionID WebFrameLoaderClient::sessionID() const
135 {
136     RELEASE_ASSERT_NOT_REACHED();
137     return PAL::SessionID::defaultSessionID();
138 }
139
140 bool WebFrameLoaderClient::hasWebView() const
141 {
142     return m_webFrame->webView();
143 }
144
145 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*)
146 {
147     notImplemented();
148 }
149
150 void WebFrameLoaderClient::forceLayoutForNonHTML()
151 {
152     notImplemented();
153 }
154
155 void WebFrameLoaderClient::setCopiesOnScroll()
156 {
157     notImplemented();
158 }
159
160 void WebFrameLoaderClient::detachedFromParent2()
161 {
162     notImplemented();
163 }
164
165 void WebFrameLoaderClient::detachedFromParent3()
166 {
167     notImplemented();
168 }
169
170 void WebFrameLoaderClient::convertMainResourceLoadToDownload(DocumentLoader* documentLoader, PAL::SessionID, const ResourceRequest& request, const ResourceResponse& response)
171 {
172     COMPtr<IWebDownloadDelegate> downloadDelegate;
173     COMPtr<IWebView> webView;
174     if (SUCCEEDED(m_webFrame->webView(&webView))) {
175         if (FAILED(webView->downloadDelegate(&downloadDelegate))) {
176             // If the WebView doesn't successfully provide a download delegate we'll pass a null one
177             // into the WebDownload - which may or may not decide to use a DefaultDownloadDelegate
178             LOG_ERROR("Failed to get downloadDelegate from WebView");
179             downloadDelegate = 0;
180         }
181     }
182
183     // Its the delegate's job to ref the WebDownload to keep it alive - otherwise it will be destroyed
184     // when this method returns
185     COMPtr<WebDownload> download;
186     download.adoptRef(WebDownload::createInstance(documentLoader->mainResourceLoader()->handle(), request, response, downloadDelegate.get()));
187 }
188
189 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
190 {
191     notImplemented();
192     return false;
193 }
194
195 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
196 {
197     WebView* webView = m_webFrame->webView();
198     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
199     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
200         return;
201
202     COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
203     resourceLoadDelegate->identifierForInitialRequest(webView, webURLRequest.get(), getWebDataSource(loader), identifier);
204 }
205
206 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader* loader, unsigned long identifier)
207 {
208     WebView* webView = m_webFrame->webView();
209     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
210     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
211         return true;
212
213     COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate;
214     if (FAILED(resourceLoadDelegate->QueryInterface(IID_IWebResourceLoadDelegatePrivate, reinterpret_cast<void**>(&resourceLoadDelegatePrivate))))
215         return true;
216
217     BOOL shouldUse;
218     if (SUCCEEDED(resourceLoadDelegatePrivate->shouldUseCredentialStorage(webView, identifier, getWebDataSource(loader), &shouldUse)))
219         return shouldUse;
220
221     return true;
222 }
223
224 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
225 {
226     ASSERT(challenge.authenticationClient());
227
228     WebView* webView = m_webFrame->webView();
229     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
230     if (SUCCEEDED(webView->resourceLoadDelegate(&resourceLoadDelegate))) {
231         COMPtr<WebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
232         if (SUCCEEDED(resourceLoadDelegate->didReceiveAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader))))
233             return;
234     }
235
236     // If the ResourceLoadDelegate doesn't exist or fails to handle the call, we tell the ResourceHandle
237     // to continue without credential - this is the best approximation of Mac behavior
238     challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge);
239 }
240
241 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
242 {
243     WebView* webView = m_webFrame->webView();
244     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
245     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
246         return;
247
248     COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
249     COMPtr<WebURLResponse> webURLRedirectResponse(AdoptCOM, WebURLResponse::createInstance(redirectResponse));
250
251     COMPtr<IWebURLRequest> newWebURLRequest;
252     if (FAILED(resourceLoadDelegate->willSendRequest(webView, identifier, webURLRequest.get(), webURLRedirectResponse.get(), getWebDataSource(loader), &newWebURLRequest)))
253         return;
254
255     if (webURLRequest == newWebURLRequest)
256         return;
257
258     if (!newWebURLRequest) {
259         request = ResourceRequest();
260         return;
261     }
262
263     COMPtr<WebMutableURLRequest> newWebURLRequestImpl(Query, newWebURLRequest);
264     if (!newWebURLRequestImpl)
265         return;
266
267     request = newWebURLRequestImpl->resourceRequest();
268 }
269
270 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
271 {
272     WebView* webView = m_webFrame->webView();
273     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
274     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
275         return;
276
277     COMPtr<WebURLResponse> webURLResponse(AdoptCOM, WebURLResponse::createInstance(response));
278     resourceLoadDelegate->didReceiveResponse(webView, identifier, webURLResponse.get(), getWebDataSource(loader));
279 }
280
281 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length)
282 {
283     WebView* webView = m_webFrame->webView();
284     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
285     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
286         return;
287
288     resourceLoadDelegate->didReceiveContentLength(webView, identifier, length, getWebDataSource(loader));
289 }
290
291 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
292 {
293     WebView* webView = m_webFrame->webView();
294     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
295     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
296         return;
297
298     resourceLoadDelegate->didFinishLoadingFromDataSource(webView, identifier, getWebDataSource(loader));
299 }
300
301 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
302 {
303     WebView* webView = m_webFrame->webView();
304     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
305     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
306         return;
307
308     COMPtr<WebError> webError(AdoptCOM, WebError::createInstance(error));
309     resourceLoadDelegate->didFailLoadingWithError(webView, identifier, webError.get(), getWebDataSource(loader));
310 }
311
312 #if USE(CFURLCONNECTION)
313 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, const unsigned char* data, const unsigned long long length)
314 {
315     WebView* webView = m_webFrame->webView();
316     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
317     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
318         return true;
319
320     COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate(Query, resourceLoadDelegate);
321     if (!resourceLoadDelegatePrivate)
322         return true;
323
324     COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(response));
325     BOOL shouldCache;
326     if (SUCCEEDED(resourceLoadDelegatePrivate->shouldCacheResponse(webView, identifier, urlResponse.get(), data, length, getWebDataSource(loader), &shouldCache)))
327         return shouldCache;
328
329     return true;
330 }
331 #endif
332
333 void WebFrameLoaderClient::dispatchDidDispatchOnloadEvents()
334 {
335     WebView* webView = m_webFrame->webView();
336     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
337     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
338         frameLoadDelegatePriv->didHandleOnloadEventsForFrame(webView, m_webFrame);
339 }
340
341 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
342 {
343     WebView* webView = m_webFrame->webView();
344     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
345     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
346         frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(webView, m_webFrame);
347 }
348
349 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
350 {
351     WebView* webView = m_webFrame->webView();
352     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
353     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
354         frameLoadDelegate->didCancelClientRedirectForFrame(webView, m_webFrame);
355 }
356
357 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const URL& url, double delay, WallTime fireDate, WebCore::LockBackForwardList)
358 {
359     WebView* webView = m_webFrame->webView();
360     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
361     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
362         frameLoadDelegate->willPerformClientRedirectToURL(webView, BString(url.string()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate.secondsSinceEpoch().seconds()), m_webFrame);
363 }
364
365 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
366 {
367     WebView* webView = m_webFrame->webView();
368     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
369     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
370         frameLoadDelegate->didChangeLocationWithinPageForFrame(webView, m_webFrame);
371 }
372
373 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
374 {
375     WebView* webView = m_webFrame->webView();
376     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
377     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
378         return;
379
380     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
381     if (!frameLoadDelegatePriv2)
382         return;
383
384     frameLoadDelegatePriv2->didPushStateWithinPageForFrame(webView, m_webFrame);
385 }
386
387 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
388 {
389     WebView* webView = m_webFrame->webView();
390     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
391     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
392         return;
393
394     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
395     if (!frameLoadDelegatePriv2)
396         return;
397
398     frameLoadDelegatePriv2->didReplaceStateWithinPageForFrame(webView, m_webFrame);
399 }
400
401 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
402 {
403     WebView* webView = m_webFrame->webView();
404     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
405     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
406         return;
407
408     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
409     if (!frameLoadDelegatePriv2)
410         return;
411
412     frameLoadDelegatePriv2->didPopStateWithinPageForFrame(webView, m_webFrame);
413 }
414 void WebFrameLoaderClient::dispatchWillClose()
415 {
416     WebView* webView = m_webFrame->webView();
417     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
418     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
419         frameLoadDelegate->willCloseFrame(webView, m_webFrame);
420 }
421
422 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
423 {
424     WebView* webView = m_webFrame->webView();
425     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
426     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
427         frameLoadDelegate->didStartProvisionalLoadForFrame(webView, m_webFrame);
428 }
429
430 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
431 {
432     WebView* webView = m_webFrame->webView();
433     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
434     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
435         // FIXME: use direction of title.
436         frameLoadDelegate->didReceiveTitle(webView, BString(title.string), m_webFrame);
437 }
438
439 void WebFrameLoaderClient::dispatchDidCommitLoad(std::optional<HasInsecureContent>)
440 {
441     WebView* webView = m_webFrame->webView();
442     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
443     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
444         frameLoadDelegate->didCommitLoadForFrame(webView, m_webFrame);
445 }
446
447 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
448 {
449     WebView* webView = m_webFrame->webView();
450     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
451     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) {
452         COMPtr<IWebError> webError;
453         webError.adoptRef(WebError::createInstance(error));
454         frameLoadDelegate->didFailProvisionalLoadWithError(webView, webError.get(), m_webFrame);
455     }
456 }
457
458 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
459 {
460     WebView* webView = m_webFrame->webView();
461     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
462     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) {
463         COMPtr<IWebError> webError;
464         webError.adoptRef(WebError::createInstance(error));
465         frameLoadDelegate->didFailLoadWithError(webView, webError.get(), m_webFrame);
466     }
467 }
468
469 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
470 {
471     WebView* webView = m_webFrame->webView();
472     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
473     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
474         frameLoadDelegatePriv->didFinishDocumentLoadForFrame(webView, m_webFrame);
475 }
476
477 void WebFrameLoaderClient::dispatchDidFinishLoad()
478 {
479     WebView* webView = m_webFrame->webView();
480     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
481     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
482         frameLoadDelegate->didFinishLoadForFrame(webView, m_webFrame);
483 }
484
485 void WebFrameLoaderClient::dispatchDidReachLayoutMilestone(OptionSet<WebCore::LayoutMilestone> milestones)
486 {
487     WebView* webView = m_webFrame->webView();
488
489     if (milestones & DidFirstLayout) {
490         COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePrivate;
491         if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate)
492             frameLoadDelegatePrivate->didFirstLayoutInFrame(webView, m_webFrame);
493     }
494
495     if (milestones & DidFirstVisuallyNonEmptyLayout) {
496         COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePrivate;
497         if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate)
498             frameLoadDelegatePrivate->didFirstVisuallyNonEmptyLayoutInFrame(webView, m_webFrame);
499     }
500 }
501
502 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction)
503 {
504     WebView* webView = m_webFrame->webView();
505
506     COMPtr<IWebUIDelegate> ui;
507     if (FAILED(webView->uiDelegate(&ui)))
508         return 0;
509
510     COMPtr<IWebView> newWebView;
511     COMPtr<WebMutableURLRequest> request = adoptCOM(WebMutableURLRequest::createInstance(ResourceRequest(navigationAction.url())));
512     if (FAILED(ui->createWebViewWithRequest(webView, request.get(), &newWebView)) || !newWebView)
513         return 0;
514
515     COMPtr<IWebFrame> mainFrame;
516     if (FAILED(newWebView->mainFrame(&mainFrame)))
517         return 0;
518
519     COMPtr<WebFrame> mainFrameImpl(Query, mainFrame);
520     return core(mainFrameImpl.get());
521 }
522
523 void WebFrameLoaderClient::dispatchShow()
524 {
525     WebView* webView = m_webFrame->webView();
526     COMPtr<IWebUIDelegate> ui;
527     if (SUCCEEDED(webView->uiDelegate(&ui)))
528         ui->webViewShow(webView);
529 }
530
531 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, FramePolicyFunction&& function)
532 {
533     WebView* webView = m_webFrame->webView();
534     Frame* coreFrame = core(m_webFrame);
535     ASSERT(coreFrame);
536
537     COMPtr<IWebPolicyDelegate> policyDelegate;
538     if (FAILED(webView->policyDelegate(&policyDelegate)))
539         policyDelegate = DefaultPolicyDelegate::sharedInstance();
540
541     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
542
543     if (SUCCEEDED(policyDelegate->decidePolicyForMIMEType(webView, BString(response.mimeType()), urlRequest.get(), m_webFrame, setUpPolicyListener(WTFMove(function)).get())))
544         return;
545
546     m_policyListenerPrivate->m_policyFunction(PolicyAction::Use);
547 }
548
549 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const NavigationAction& action, const ResourceRequest& request, FormState* formState, const String& frameName, FramePolicyFunction&& function)
550 {
551     WebView* webView = m_webFrame->webView();
552     Frame* coreFrame = core(m_webFrame);
553     ASSERT(coreFrame);
554
555     COMPtr<IWebPolicyDelegate> policyDelegate;
556     if (FAILED(webView->policyDelegate(&policyDelegate)))
557         policyDelegate = DefaultPolicyDelegate::sharedInstance();
558
559     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
560     COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, formState ? &formState->form() : nullptr, coreFrame));
561
562     if (SUCCEEDED(policyDelegate->decidePolicyForNewWindowAction(webView, actionInformation.get(), urlRequest.get(), BString(frameName), setUpPolicyListener(WTFMove(function)).get())))
563         return;
564
565     m_policyListenerPrivate->m_policyFunction(PolicyAction::Use);
566 }
567
568 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& action, const ResourceRequest& request, const ResourceResponse&, FormState* formState, WebCore::PolicyDecisionMode, WebCore::ShouldSkipSafeBrowsingCheck, FramePolicyFunction&& function)
569 {
570     WebView* webView = m_webFrame->webView();
571     Frame* coreFrame = core(m_webFrame);
572     ASSERT(coreFrame);
573
574     COMPtr<IWebPolicyDelegate> policyDelegate;
575     if (FAILED(webView->policyDelegate(&policyDelegate)))
576         policyDelegate = DefaultPolicyDelegate::sharedInstance();
577
578     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
579     COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, formState ? &formState->form() : nullptr, coreFrame));
580
581     if (SUCCEEDED(policyDelegate->decidePolicyForNavigationAction(webView, actionInformation.get(), urlRequest.get(), m_webFrame, setUpPolicyListener(WTFMove(function)).get())))
582         return;
583
584     m_policyListenerPrivate->m_policyFunction(PolicyAction::Use);
585 }
586
587 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
588 {
589     WebView* webView = m_webFrame->webView();
590     COMPtr<IWebPolicyDelegate> policyDelegate;
591     if (FAILED(webView->policyDelegate(&policyDelegate)))
592         policyDelegate = DefaultPolicyDelegate::sharedInstance();
593
594     COMPtr<IWebError> webError(AdoptCOM, WebError::createInstance(error));
595     policyDelegate->unableToImplementPolicyWithError(webView, webError.get(), m_webFrame);
596 }
597
598 void WebFrameLoaderClient::dispatchWillSendSubmitEvent(Ref<WebCore::FormState>&&)
599 {
600 }
601
602 void WebFrameLoaderClient::dispatchWillSubmitForm(FormState& formState, CompletionHandler<void()>&& completionHandler)
603 {
604     WebView* webView = m_webFrame->webView();
605     Frame* coreFrame = core(m_webFrame);
606     ASSERT(coreFrame);
607
608     COMPtr<IWebFormDelegate> formDelegate;
609
610     if (FAILED(webView->formDelegate(&formDelegate))) {
611         completionHandler();
612         return;
613     }
614
615     COMPtr<IDOMElement> formElement(AdoptCOM, DOMElement::createInstance(&formState.form()));
616
617     HashMap<String, String> formValuesMap;
618     const StringPairVector& textFieldValues = formState.textFieldValues();
619     size_t size = textFieldValues.size();
620     for (size_t i = 0; i < size; ++i)
621         formValuesMap.add(textFieldValues[i].first, textFieldValues[i].second);
622
623     COMPtr<IPropertyBag> formValuesPropertyBag(AdoptCOM, COMPropertyBag<String>::createInstance(formValuesMap));
624
625     COMPtr<WebFrame> sourceFrame(kit(formState.sourceDocument().frame()));
626     if (SUCCEEDED(formDelegate->willSubmitForm(m_webFrame, sourceFrame.get(), formElement.get(), formValuesPropertyBag.get(), setUpPolicyListener([completionHandler = WTFMove(completionHandler)] (PolicyAction) mutable { completionHandler(); }).get())))
627         return;
628
629     // FIXME: Add a sane default implementation
630     completionHandler();
631 }
632
633 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
634 {
635     if (!m_manualLoader)
636         return;
637
638     m_manualLoader->didFail(error);
639     m_manualLoader = 0;
640     m_hasSentResponseToPlugin = false;
641 }
642
643 void WebFrameLoaderClient::progressStarted(WebCore::Frame&)
644 {
645     static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
646     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
647     notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
648 }
649
650 void WebFrameLoaderClient::progressEstimateChanged(WebCore::Frame&)
651 {
652     static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
653     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
654     notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
655 }
656
657 void WebFrameLoaderClient::progressFinished(WebCore::Frame&)
658 {
659     static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
660     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
661     notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
662 }
663
664 void WebFrameLoaderClient::startDownload(const ResourceRequest& request, const String& /* suggestedName */)
665 {
666     m_webFrame->webView()->downloadURL(request.url());
667 }
668
669 void WebFrameLoaderClient::willChangeTitle(DocumentLoader*)
670 {
671     notImplemented();
672 }
673
674 void WebFrameLoaderClient::didChangeTitle(DocumentLoader*)
675 {
676     notImplemented();
677 }
678
679 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
680 {
681     if (!m_manualLoader)
682         loader->commitData(data, length);
683
684     // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
685     // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
686     Frame* coreFrame = core(m_webFrame);
687     if (coreFrame->document()->isMediaDocument())
688         loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
689
690     if (!m_manualLoader)
691         return;
692
693     if (!m_hasSentResponseToPlugin) {
694         m_manualLoader->didReceiveResponse(loader->response());
695         // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
696         // setting up this stream can cause the main document load to be cancelled, setting m_manualLoader
697         // to null
698         if (!m_manualLoader)
699             return;
700         m_hasSentResponseToPlugin = true;
701     }
702     m_manualLoader->didReceiveData(data, length);
703 }
704
705 void WebFrameLoaderClient::finishedLoading(DocumentLoader*)
706 {
707     if (!m_manualLoader)
708         return;
709
710     m_manualLoader->didFinishLoading();
711     m_manualLoader = 0;
712     m_hasSentResponseToPlugin = false;
713 }
714
715 void WebFrameLoaderClient::updateGlobalHistory()
716 {
717     DocumentLoader* loader = core(m_webFrame)->loader().documentLoader();
718     WebView* webView = m_webFrame->webView();
719     COMPtr<IWebHistoryDelegate> historyDelegate;
720     webView->historyDelegate(&historyDelegate);
721
722     if (historyDelegate) {
723         COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(loader->response()));
724         COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(loader->originalRequestCopy()));
725         
726         COMPtr<IWebNavigationData> navigationData(AdoptCOM, WebNavigationData::createInstance(
727             loader->urlForHistory(), loader->title().string, urlRequest.get(), urlResponse.get(), loader->substituteData().isValid(), loader->clientRedirectSourceForHistory()));
728
729         historyDelegate->didNavigateWithNavigationData(webView, navigationData.get(), m_webFrame);
730         return;
731     }
732
733     WebHistory* history = WebHistory::sharedHistory();
734     if (!history)
735         return;
736
737     history->visitedURL(loader->urlForHistory(), loader->title().string, loader->originalRequestCopy().httpMethod(), loader->urlForHistoryReflectsFailure(), !loader->clientRedirectSourceForHistory());
738 }
739
740 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
741 {
742     WebView* webView = m_webFrame->webView();
743     COMPtr<IWebHistoryDelegate> historyDelegate;
744     webView->historyDelegate(&historyDelegate);
745
746     WebHistory* history = WebHistory::sharedHistory();
747
748     DocumentLoader* loader = core(m_webFrame)->loader().documentLoader();
749     ASSERT(loader->unreachableURL().isEmpty());
750
751     if (!loader->clientRedirectSourceForHistory().isNull()) {
752         if (historyDelegate) {
753             BString sourceURL(loader->clientRedirectSourceForHistory());
754             BString destURL(loader->clientRedirectDestinationForHistory());
755             historyDelegate->didPerformClientRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
756         }
757     }
758
759     if (!loader->serverRedirectSourceForHistory().isNull()) {
760         if (historyDelegate) {
761             BString sourceURL(loader->serverRedirectSourceForHistory());
762             BString destURL(loader->serverRedirectDestinationForHistory());
763             historyDelegate->didPerformServerRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
764         }
765     }
766 }
767
768 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem&) const
769 {
770     return true;
771 }
772
773 void WebFrameLoaderClient::didDisplayInsecureContent()
774 {
775     WebView* webView = m_webFrame->webView();
776     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
777     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
778         return;
779
780     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
781     if (!frameLoadDelegatePriv2)
782         return;
783
784     frameLoadDelegatePriv2->didDisplayInsecureContent(webView);
785 }
786
787 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin& origin, const URL& insecureURL)
788 {
789     COMPtr<IWebSecurityOrigin> webSecurityOrigin = WebSecurityOrigin::createInstance(&origin);
790
791     WebView* webView = m_webFrame->webView();
792     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
793     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
794         return;
795
796     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
797     if (!frameLoadDelegatePriv2)
798         return;
799
800     frameLoadDelegatePriv2->didRunInsecureContent(webView, webSecurityOrigin.get());
801 }
802
803 void WebFrameLoaderClient::didDetectXSS(const URL&, bool)
804 {
805     // FIXME: propogate call into the private delegate.
806 }
807
808 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
809 {
810     // FIXME: Need ChickenCat to include CFNetwork/CFURLError.h to get these values
811     // Alternatively, we could create our own error domain/codes.
812     return ResourceError(String(WebURLErrorDomain), -999, request.url(), String("Cancelled"));
813 }
814
815 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
816 {
817     return ResourceError(String(WebKitErrorDomain), WebKitErrorCannotUseRestrictedPort, request.url(), WEB_UI_STRING("Not allowed to use restricted network port", "WebKitErrorCannotUseRestrictedPort description"));
818 }
819
820 ResourceError WebFrameLoaderClient::blockedByContentBlockerError(const ResourceRequest& request)
821 {
822     RELEASE_ASSERT_NOT_REACHED(); // Content Blockers are not enabled for WK1.
823 }
824
825 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
826 {
827     return ResourceError(String(WebKitErrorDomain), WebKitErrorCannotShowURL, request.url(), WEB_UI_STRING("The URL can\xE2\x80\x99t be shown", "WebKitErrorCannotShowURL description"));
828 }
829
830 ResourceError WebFrameLoaderClient::interruptedForPolicyChangeError(const ResourceRequest& request)
831 {
832     return ResourceError(String(WebKitErrorDomain), WebKitErrorFrameLoadInterruptedByPolicyChange, request.url(), WEB_UI_STRING("Frame load interrupted", "WebKitErrorFrameLoadInterruptedByPolicyChange description"));
833 }
834
835 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
836 {
837     return ResourceError(String(), WebKitErrorCannotShowMIMEType, response.url(), WEB_UI_STRING("Content with specified MIME type can\xE2\x80\x99t be shown", "WebKitErrorCannotShowMIMEType description"));
838 }
839
840 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
841 {
842     return ResourceError(String(WebURLErrorDomain), -1100, response.url(), String("File does not exist."));
843 }
844
845 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
846 {
847     return ResourceError(String(WebKitErrorDomain), WebKitErrorPlugInWillHandleLoad, response.url(), WEB_UI_STRING("Plug-in handled load", "WebKitErrorPlugInWillHandleLoad description"));
848 }
849
850 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
851 {
852     if (error.errorCode() == WebURLErrorCancelled && error.domain() == String(WebURLErrorDomain))
853         return false;
854
855     if (error.errorCode() == WebKitErrorPlugInWillHandleLoad && error.domain() == String(WebKitErrorDomain))
856         return false;
857
858     return true;
859 }
860
861 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest& request) const
862 {
863     return WebView::canHandleRequest(request);
864 }
865
866 bool WebFrameLoaderClient::canShowMIMEType(const String& mimeType) const
867 {
868     return m_webFrame->webView()->canShowMIMEType(mimeType);
869 }
870
871 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& mimeType) const
872 {
873     return m_webFrame->webView()->canShowMIMETypeAsHTML(mimeType);
874 }
875
876 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& /*URLScheme*/) const
877 {
878     notImplemented();
879     return false;
880 }
881
882 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const
883 {
884     notImplemented();
885     ASSERT_NOT_REACHED();
886     return String();
887 }
888
889 void WebFrameLoaderClient::frameLoadCompleted()
890 {
891 }
892
893 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem&)
894 {
895 }
896
897 void WebFrameLoaderClient::restoreViewState()
898 {
899 }
900
901 void WebFrameLoaderClient::provisionalLoadStarted()
902 {
903     notImplemented();
904 }
905
906 void WebFrameLoaderClient::didFinishLoad()
907 {
908     notImplemented();
909 }
910
911 void WebFrameLoaderClient::prepareForDataSourceReplacement()
912 {
913     notImplemented();
914 }
915
916 Ref<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
917 {
918     Ref<WebDocumentLoader> loader = WebDocumentLoader::create(request, substituteData);
919
920     COMPtr<WebDataSource> dataSource(AdoptCOM, WebDataSource::createInstance(loader.ptr()));
921
922     loader->setDataSource(dataSource.get());
923     return WTFMove(loader);
924 }
925
926 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const URL& url)
927 {
928     WebView* webView = m_webFrame->webView();
929     COMPtr<IWebHistoryDelegate> historyDelegate;
930     webView->historyDelegate(&historyDelegate);
931     if (historyDelegate) {
932         BString titleBSTR(title.string);
933         BString urlBSTR(url.string());
934         historyDelegate->updateHistoryTitle(webView, titleBSTR, urlBSTR);
935         return;
936     }
937
938     BOOL privateBrowsingEnabled = FALSE;
939     COMPtr<IWebPreferences> preferences;
940     if (SUCCEEDED(m_webFrame->webView()->preferences(&preferences)))
941         preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
942     if (privateBrowsingEnabled)
943         return;
944
945     // update title in global history
946     COMPtr<WebHistory> history = webHistory();
947     if (!history)
948         return;
949
950     COMPtr<IWebHistoryItem> item;
951     if (FAILED(history->itemForURL(BString(url.string()), &item)))
952         return;
953
954     COMPtr<IWebHistoryItemPrivate> itemPrivate(Query, item);
955     if (!itemPrivate)
956         return;
957
958     itemPrivate->setTitle(BString(title.string));
959 }
960
961 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
962 {
963 #if USE(CFURLCONNECTION)
964     Frame* coreFrame = core(m_webFrame);
965     if (!coreFrame)
966         return;
967
968     ASSERT(coreFrame->loader().documentLoader() == cachedFrame->documentLoader());
969
970     cachedFrame->setCachedFramePlatformData(std::make_unique<WebCachedFramePlatformData>(static_cast<IWebDataSource*>(getWebDataSource(coreFrame->loader().documentLoader()))));
971 #else
972     notImplemented();
973 #endif
974 }
975
976 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
977 {
978 }
979
980 void WebFrameLoaderClient::transitionToCommittedForNewPage()
981 {
982     WebView* view = m_webFrame->webView();
983
984     RECT pixelRect;
985     view->frameRect(&pixelRect);
986     bool transparent = view->transparent();
987     Color backgroundColor = transparent ? Color::transparent : Color::white;
988     FloatRect logicalFrame(pixelRect);
989     logicalFrame.scale(1.0f / view->deviceScaleFactor());
990     core(m_webFrame)->createView(enclosingIntRect(logicalFrame).size(), backgroundColor, transparent, /* fixedLayoutSize */ { }, /* fixedVisibleContentRect */ { });
991 }
992
993 void WebFrameLoaderClient::didSaveToPageCache()
994 {
995 }
996
997 void WebFrameLoaderClient::didRestoreFromPageCache()
998 {
999 }
1000
1001 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool)
1002 {
1003 }
1004
1005 String WebFrameLoaderClient::userAgent(const URL& url)
1006 {
1007     return m_webFrame->webView()->userAgentForKURL(url);
1008 }
1009
1010 bool WebFrameLoaderClient::canCachePage() const
1011 {
1012     return true;
1013 }
1014
1015 RefPtr<Frame> WebFrameLoaderClient::createFrame(const URL& url, const String& name, HTMLFrameOwnerElement& ownerElement,
1016     const String& referrer)
1017 {
1018     Frame* coreFrame = core(m_webFrame);
1019     ASSERT(coreFrame);
1020
1021     COMPtr<WebFrame> webFrame(AdoptCOM, WebFrame::createInstance());
1022
1023     RefPtr<Frame> childFrame = webFrame->createSubframeWithOwnerElement(m_webFrame->webView(), coreFrame->page(), &ownerElement);
1024
1025     childFrame->tree().setName(name);
1026     coreFrame->tree().appendChild(*childFrame);
1027     childFrame->init();
1028
1029     coreFrame->loader().loadURLIntoChildFrame(url, referrer, childFrame.get());
1030
1031     // The frame's onload handler may have removed it from the document.
1032     if (!childFrame->tree().parent())
1033         return nullptr;
1034
1035     return childFrame;
1036 }
1037
1038 ObjectContentType WebFrameLoaderClient::objectContentType(const URL& url, const String& mimeTypeIn)
1039 {
1040     String mimeType = mimeTypeIn;
1041
1042     if (mimeType.isEmpty()) {
1043         String decodedPath = decodeURLEscapeSequences(url.path());
1044         mimeType = PluginDatabase::installedPlugins()->MIMETypeForExtension(decodedPath.substring(decodedPath.reverseFind('.') + 1));
1045     }
1046
1047     if (mimeType.isEmpty())
1048         return ObjectContentType::Frame; // Go ahead and hope that we can display the content.
1049
1050     bool plugInSupportsMIMEType = PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType);
1051
1052     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1053         return WebCore::ObjectContentType::Image;
1054
1055     if (plugInSupportsMIMEType)
1056         return WebCore::ObjectContentType::PlugIn;
1057
1058     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1059         return WebCore::ObjectContentType::Frame;
1060
1061     return WebCore::ObjectContentType::None;
1062 }
1063
1064 void WebFrameLoaderClient::dispatchDidFailToStartPlugin(const PluginView* pluginView) const
1065 {
1066     WebView* webView = m_webFrame->webView();
1067
1068     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
1069     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
1070         return;
1071
1072     RetainPtr<CFMutableDictionaryRef> userInfo = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
1073
1074     Frame* frame = core(m_webFrame);
1075     ASSERT(frame == pluginView->parentFrame());
1076
1077     if (!pluginView->pluginsPage().isNull()) {
1078         URL pluginPageURL = frame->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(pluginView->pluginsPage()));
1079         if (pluginPageURL.protocolIsInHTTPFamily()) {
1080             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
1081             CFDictionarySetValue(userInfo.get(), key, pluginPageURL.string().createCFString().get());
1082         }
1083     }
1084
1085     if (!pluginView->mimeType().isNull()) {
1086         static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
1087         CFDictionarySetValue(userInfo.get(), key, pluginView->mimeType().createCFString().get());
1088     }
1089
1090     if (pluginView->plugin()) {
1091         String pluginName = pluginView->plugin()->name();
1092         if (!pluginName.isNull()) {
1093             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
1094             CFDictionarySetValue(userInfo.get(), key, pluginName.createCFString().get());
1095         }
1096     }
1097
1098     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
1099     userInfoBag->setDictionary(userInfo.get());
1100  
1101     int errorCode = 0;
1102     String description;
1103     switch (pluginView->status()) {
1104         case PluginStatusCanNotFindPlugin:
1105             errorCode = WebKitErrorCannotFindPlugIn;
1106             description = WEB_UI_STRING("The plug-in can\xE2\x80\x99t be found", "WebKitErrorCannotFindPlugin description");
1107             break;
1108         case PluginStatusCanNotLoadPlugin:
1109             errorCode = WebKitErrorCannotLoadPlugIn;
1110             description = WEB_UI_STRING("The plug-in can\xE2\x80\x99t be loaded", "WebKitErrorCannotLoadPlugin description");
1111             break;
1112         default:
1113             ASSERT_NOT_REACHED();
1114     }
1115
1116     ResourceError resourceError(String(WebKitErrorDomain), errorCode, pluginView->url(), String());
1117     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
1118      
1119     resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader().documentLoader()));
1120 }
1121
1122 RefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize& pluginSize, HTMLPlugInElement& element, const URL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1123 {
1124     WebView* webView = m_webFrame->webView();
1125
1126     COMPtr<IWebUIDelegate> ui;
1127     if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) {
1128         COMPtr<IWebUIDelegatePrivate> uiPrivate(Query, ui);
1129
1130         if (uiPrivate) {
1131             // Assemble the view arguments in a property bag.
1132             HashMap<String, String> viewArguments;
1133             for (unsigned i = 0; i < paramNames.size(); i++) 
1134                 viewArguments.set(paramNames[i], paramValues[i]);
1135             COMPtr<IPropertyBag> viewArgumentsBag(AdoptCOM, COMPropertyBag<String>::adopt(viewArguments));
1136             COMPtr<IDOMElement> containingElement(AdoptCOM, DOMElement::createInstance(&element));
1137
1138             HashMap<String, COMVariant> arguments;
1139
1140             arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag);
1141             arguments.set(WebEmbeddedViewBaseURLKey, url.string());
1142             arguments.set(WebEmbeddedViewContainingElementKey, containingElement);
1143             arguments.set(WebEmbeddedViewMIMETypeKey, mimeType);
1144
1145             COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMVariant>::adopt(arguments));
1146
1147             COMPtr<IWebEmbeddedView> view;
1148             HRESULT result = uiPrivate->embeddedViewWithArguments(webView, m_webFrame, argumentsBag.get(), &view);
1149             if (SUCCEEDED(result)) {
1150                 HWND parentWindow;
1151                 HRESULT hr = webView->viewWindow(&parentWindow);
1152                 ASSERT(SUCCEEDED(hr));
1153
1154                 return EmbeddedWidget::create(view.get(), &element, parentWindow, pluginSize);
1155             }
1156         }
1157     }
1158
1159 #if ENABLE(NETSCAPE_PLUGIN_API)
1160     Frame* frame = core(m_webFrame);
1161     RefPtr<PluginView> pluginView = PluginView::create(frame, pluginSize, &element, url, paramNames, paramValues, mimeType, loadManually);
1162
1163     if (pluginView->status() == PluginStatusLoadedSuccessfully)
1164         return pluginView;
1165
1166     dispatchDidFailToStartPlugin(pluginView.get());
1167 #endif
1168     return nullptr;
1169 }
1170
1171 void WebFrameLoaderClient::redirectDataToPlugin(Widget& pluginWidget)
1172 {
1173     // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
1174     if (pluginWidget.isPluginView())
1175         m_manualLoader = toPluginView(&pluginWidget);
1176     else 
1177         m_manualLoader = static_cast<EmbeddedWidget*>(&pluginWidget);
1178 }
1179
1180 RefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement& element, const URL& /*baseURL*/, const Vector<String>& paramNames, const Vector<String>& paramValues)
1181 {
1182 #if ENABLE(NETSCAPE_PLUGIN_API)
1183     RefPtr<PluginView> pluginView = PluginView::create(core(m_webFrame), pluginSize, &element, URL(), paramNames, paramValues, "application/x-java-applet", false);
1184
1185     // Check if the plugin can be loaded successfully
1186     if (pluginView->plugin() && pluginView->plugin()->load())
1187         return WTFMove(pluginView);
1188
1189     WebView* webView = m_webFrame->webView();
1190     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
1191     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
1192         return WTFMove(pluginView);
1193
1194     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
1195
1196     ResourceError resourceError(String(WebKitErrorDomain), WebKitErrorJavaUnavailable, URL(), WEB_UI_STRING("Java is unavailable", "WebKitErrorJavaUnavailable description"));
1197     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
1198
1199     Frame* coreFrame = core(m_webFrame);
1200     ASSERT(coreFrame);
1201
1202     resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(coreFrame->loader().documentLoader()));
1203
1204     return WTFMove(pluginView);
1205 #else
1206     return nullptr;
1207 #endif
1208 }
1209
1210 WebHistory* WebFrameLoaderClient::webHistory() const
1211 {
1212     if (m_webFrame != m_webFrame->webView()->topLevelFrame())
1213         return 0;
1214
1215     return WebHistory::sharedHistory();
1216 }
1217
1218 String WebFrameLoaderClient::overrideMediaType() const
1219 {
1220     notImplemented();
1221     return String();
1222 }
1223
1224 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
1225 {
1226     Frame* coreFrame = core(m_webFrame);
1227     ASSERT(coreFrame);
1228
1229     if (!coreFrame->settings().isScriptEnabled())
1230         return;
1231
1232     WebView* webView = m_webFrame->webView();
1233     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1234     if (FAILED(webView->frameLoadDelegate(&frameLoadDelegate)))
1235         return;
1236
1237     COMPtr<IWebFrameLoadDelegatePrivate2> delegatePrivate(Query, frameLoadDelegate);
1238     if (delegatePrivate && delegatePrivate->didClearWindowObjectForFrameInScriptWorld(webView, m_webFrame, WebScriptWorld::findOrCreateWorld(world).get()) != E_NOTIMPL)
1239         return;
1240
1241     if (&world != &mainThreadNormalWorld())
1242         return;
1243
1244     JSContextRef context = toRef(coreFrame->script().globalObject(world)->globalExec());
1245     JSObjectRef windowObject = toRef(coreFrame->script().globalObject(world));
1246     ASSERT(windowObject);
1247
1248     if (FAILED(frameLoadDelegate->didClearWindowObject(webView, context, windowObject, m_webFrame)))
1249         frameLoadDelegate->windowScriptObjectAvailable(webView, context, windowObject);
1250 }
1251
1252 Ref<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1253 {
1254     return WebFrameNetworkingContext::create(core(m_webFrame));
1255 }
1256
1257 bool WebFrameLoaderClient::shouldAlwaysUsePluginDocument(const String& mimeType) const
1258 {
1259     WebView* webView = m_webFrame->webView();
1260     if (!webView)
1261         return false;
1262
1263     return webView->shouldUseEmbeddedView(mimeType);
1264 }
1265
1266 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*)
1267 {
1268     notImplemented();
1269 }
1270
1271 void WebFrameLoaderClient::setMainFrameDocumentReady(bool)
1272 {
1273     notImplemented();
1274 }
1275
1276 void WebFrameLoaderClient::cancelPolicyCheck()
1277 {
1278     if (m_policyListenerPrivate->m_policyListener) {
1279         m_policyListenerPrivate->m_policyListener->invalidate();
1280         m_policyListenerPrivate->m_policyListener = 0;
1281     }
1282
1283     m_policyListenerPrivate->m_policyFunction = nullptr;
1284 }
1285
1286 COMPtr<WebFramePolicyListener> WebFrameLoaderClient::setUpPolicyListener(WebCore::FramePolicyFunction&& function)
1287 {
1288     // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
1289
1290     if (m_policyListenerPrivate->m_policyListener)
1291         m_policyListenerPrivate->m_policyListener->invalidate();
1292
1293     Frame* coreFrame = core(m_webFrame);
1294     ASSERT(coreFrame);
1295
1296     m_policyListenerPrivate->m_policyListener.adoptRef(WebFramePolicyListener::createInstance(coreFrame));
1297     m_policyListenerPrivate->m_policyFunction = WTFMove(function);
1298
1299     return m_policyListenerPrivate->m_policyListener;
1300 }
1301
1302 void WebFrameLoaderClient::receivedPolicyDecision(PolicyAction action)
1303 {
1304     ASSERT(m_policyListenerPrivate->m_policyListener);
1305     ASSERT(m_policyListenerPrivate->m_policyFunction);
1306
1307     FramePolicyFunction function = WTFMove(m_policyListenerPrivate->m_policyFunction);
1308
1309     m_policyListenerPrivate->m_policyListener = 0;
1310
1311     Frame* coreFrame = core(m_webFrame);
1312     ASSERT(coreFrame);
1313
1314     function(action);
1315 }
1316
1317 void WebFrameLoaderClient::prefetchDNS(const String& hostname)
1318 {
1319     WebCore::prefetchDNS(hostname);
1320 }