38568c0c7e3a499e9800376000a718f7e97c7269
[WebKit-https.git] / Source / WebKit / 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 "NotImplemented.h"
38 #include "PluginDatabase.h"
39 #include "PluginPackage.h"
40 #include "PluginView.h"
41 #include "WebActionPropertyBag.h"
42 #include "WebCachedFramePlatformData.h"
43 #include "WebChromeClient.h"
44 #include "WebDocumentLoader.h"
45 #include "WebDownload.h"
46 #include "WebError.h"
47 #include "WebFrame.h"
48 #include "WebFrameNetworkingContext.h"
49 #include "WebFramePolicyListener.h"
50 #include "WebHistory.h"
51 #include "WebHistoryItem.h"
52 #include "WebMutableURLRequest.h"
53 #include "WebNavigationData.h"
54 #include "WebNotificationCenter.h"
55 #include "WebScriptWorld.h"
56 #include "WebSecurityOrigin.h"
57 #include "WebURLAuthenticationChallenge.h"
58 #include "WebURLResponse.h"
59 #include "WebView.h"
60 #include <JavaScriptCore/APICast.h>
61 #include <WebCore/BackForwardController.h>
62 #include <WebCore/CachedFrame.h>
63 #include <WebCore/DNS.h>
64 #include <WebCore/DocumentLoader.h>
65 #include <WebCore/FormState.h>
66 #include <WebCore/Frame.h>
67 #include <WebCore/FrameLoader.h>
68 #include <WebCore/FrameTree.h>
69 #include <WebCore/FrameView.h>
70 #include <WebCore/HTMLAppletElement.h>
71 #include <WebCore/HTMLFrameElement.h>
72 #include <WebCore/HTMLFrameOwnerElement.h>
73 #include <WebCore/HTMLNames.h>
74 #include <WebCore/HTMLParserIdioms.h>
75 #include <WebCore/HTMLPlugInElement.h>
76 #include <WebCore/HistoryItem.h>
77 #include <WebCore/LocalizedStrings.h>
78 #include <WebCore/MIMETypeRegistry.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 bool WebFrameLoaderClient::hasWebView() const
125 {
126     return m_webFrame->webView();
127 }
128
129 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*)
130 {
131     notImplemented();
132 }
133
134 void WebFrameLoaderClient::forceLayoutForNonHTML()
135 {
136     notImplemented();
137 }
138
139 void WebFrameLoaderClient::setCopiesOnScroll()
140 {
141     notImplemented();
142 }
143
144 void WebFrameLoaderClient::detachedFromParent2()
145 {
146     notImplemented();
147 }
148
149 void WebFrameLoaderClient::detachedFromParent3()
150 {
151     notImplemented();
152 }
153
154 void WebFrameLoaderClient::convertMainResourceLoadToDownload(DocumentLoader* documentLoader, SessionID, const ResourceRequest& request, const ResourceResponse& response)
155 {
156     COMPtr<IWebDownloadDelegate> downloadDelegate;
157     COMPtr<IWebView> webView;
158     if (SUCCEEDED(m_webFrame->webView(&webView))) {
159         if (FAILED(webView->downloadDelegate(&downloadDelegate))) {
160             // If the WebView doesn't successfully provide a download delegate we'll pass a null one
161             // into the WebDownload - which may or may not decide to use a DefaultDownloadDelegate
162             LOG_ERROR("Failed to get downloadDelegate from WebView");
163             downloadDelegate = 0;
164         }
165     }
166
167     // Its the delegate's job to ref the WebDownload to keep it alive - otherwise it will be destroyed
168     // when this method returns
169     COMPtr<WebDownload> download;
170     download.adoptRef(WebDownload::createInstance(documentLoader->mainResourceLoader()->handle(), request, response, downloadDelegate.get()));
171 }
172
173 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
174 {
175     notImplemented();
176     return false;
177 }
178
179 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
180 {
181     WebView* webView = m_webFrame->webView();
182     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
183     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
184         return;
185
186     COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
187     resourceLoadDelegate->identifierForInitialRequest(webView, webURLRequest.get(), getWebDataSource(loader), identifier);
188 }
189
190 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader* loader, unsigned long identifier)
191 {
192     WebView* webView = m_webFrame->webView();
193     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
194     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
195         return true;
196
197     COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate;
198     if (FAILED(resourceLoadDelegate->QueryInterface(IID_IWebResourceLoadDelegatePrivate, reinterpret_cast<void**>(&resourceLoadDelegatePrivate))))
199         return true;
200
201     BOOL shouldUse;
202     if (SUCCEEDED(resourceLoadDelegatePrivate->shouldUseCredentialStorage(webView, identifier, getWebDataSource(loader), &shouldUse)))
203         return shouldUse;
204
205     return true;
206 }
207
208 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
209 {
210     ASSERT(challenge.authenticationClient());
211
212     WebView* webView = m_webFrame->webView();
213     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
214     if (SUCCEEDED(webView->resourceLoadDelegate(&resourceLoadDelegate))) {
215         COMPtr<WebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
216         if (SUCCEEDED(resourceLoadDelegate->didReceiveAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader))))
217             return;
218     }
219
220     // If the ResourceLoadDelegate doesn't exist or fails to handle the call, we tell the ResourceHandle
221     // to continue without credential - this is the best approximation of Mac behavior
222     challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge);
223 }
224
225 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
226 {
227     WebView* webView = m_webFrame->webView();
228     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
229     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
230         return;
231
232     COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
233     COMPtr<WebURLResponse> webURLRedirectResponse(AdoptCOM, WebURLResponse::createInstance(redirectResponse));
234
235     COMPtr<IWebURLRequest> newWebURLRequest;
236     if (FAILED(resourceLoadDelegate->willSendRequest(webView, identifier, webURLRequest.get(), webURLRedirectResponse.get(), getWebDataSource(loader), &newWebURLRequest)))
237         return;
238
239     if (webURLRequest == newWebURLRequest)
240         return;
241
242     if (!newWebURLRequest) {
243         request = ResourceRequest();
244         return;
245     }
246
247     COMPtr<WebMutableURLRequest> newWebURLRequestImpl(Query, newWebURLRequest);
248     if (!newWebURLRequestImpl)
249         return;
250
251     request = newWebURLRequestImpl->resourceRequest();
252 }
253
254 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
255 {
256     WebView* webView = m_webFrame->webView();
257     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
258     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
259         return;
260
261     COMPtr<WebURLResponse> webURLResponse(AdoptCOM, WebURLResponse::createInstance(response));
262     resourceLoadDelegate->didReceiveResponse(webView, identifier, webURLResponse.get(), getWebDataSource(loader));
263 }
264
265 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length)
266 {
267     WebView* webView = m_webFrame->webView();
268     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
269     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
270         return;
271
272     resourceLoadDelegate->didReceiveContentLength(webView, identifier, length, getWebDataSource(loader));
273 }
274
275 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
276 {
277     WebView* webView = m_webFrame->webView();
278     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
279     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
280         return;
281
282     resourceLoadDelegate->didFinishLoadingFromDataSource(webView, identifier, getWebDataSource(loader));
283 }
284
285 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
286 {
287     WebView* webView = m_webFrame->webView();
288     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
289     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
290         return;
291
292     COMPtr<WebError> webError(AdoptCOM, WebError::createInstance(error));
293     resourceLoadDelegate->didFailLoadingWithError(webView, identifier, webError.get(), getWebDataSource(loader));
294 }
295
296 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, const unsigned char* data, const unsigned long long length)
297 {
298     WebView* webView = m_webFrame->webView();
299     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
300     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
301         return true;
302
303     COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate(Query, resourceLoadDelegate);
304     if (!resourceLoadDelegatePrivate)
305         return true;
306
307     COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(response));
308     BOOL shouldCache;
309     if (SUCCEEDED(resourceLoadDelegatePrivate->shouldCacheResponse(webView, identifier, urlResponse.get(), data, length, getWebDataSource(loader), &shouldCache)))
310         return shouldCache;
311
312     return true;
313 }
314
315 void WebFrameLoaderClient::dispatchDidDispatchOnloadEvents()
316 {
317     WebView* webView = m_webFrame->webView();
318     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
319     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
320         frameLoadDelegatePriv->didHandleOnloadEventsForFrame(webView, m_webFrame);
321 }
322
323 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
324 {
325     WebView* webView = m_webFrame->webView();
326     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
327     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
328         frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(webView, m_webFrame);
329 }
330
331 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
332 {
333     WebView* webView = m_webFrame->webView();
334     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
335     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
336         frameLoadDelegate->didCancelClientRedirectForFrame(webView, m_webFrame);
337 }
338
339 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const URL& url, double delay, double fireDate)
340 {
341     WebView* webView = m_webFrame->webView();
342     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
343     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
344         frameLoadDelegate->willPerformClientRedirectToURL(webView, BString(url.string()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), m_webFrame);
345 }
346
347 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
348 {
349     WebView* webView = m_webFrame->webView();
350     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
351     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
352         frameLoadDelegate->didChangeLocationWithinPageForFrame(webView, m_webFrame);
353 }
354
355 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
356 {
357     WebView* webView = m_webFrame->webView();
358     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
359     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
360         return;
361
362     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
363     if (!frameLoadDelegatePriv2)
364         return;
365
366     frameLoadDelegatePriv2->didPushStateWithinPageForFrame(webView, m_webFrame);
367 }
368
369 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
370 {
371     WebView* webView = m_webFrame->webView();
372     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
373     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
374         return;
375
376     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
377     if (!frameLoadDelegatePriv2)
378         return;
379
380     frameLoadDelegatePriv2->didReplaceStateWithinPageForFrame(webView, m_webFrame);
381 }
382
383 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
384 {
385     WebView* webView = m_webFrame->webView();
386     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
387     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
388         return;
389
390     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
391     if (!frameLoadDelegatePriv2)
392         return;
393
394     frameLoadDelegatePriv2->didPopStateWithinPageForFrame(webView, m_webFrame);
395 }
396 void WebFrameLoaderClient::dispatchWillClose()
397 {
398     WebView* webView = m_webFrame->webView();
399     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
400     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
401         frameLoadDelegate->willCloseFrame(webView, m_webFrame);
402 }
403
404 void WebFrameLoaderClient::dispatchDidReceiveIcon()
405 {
406     m_webFrame->webView()->dispatchDidReceiveIconFromWebFrame(m_webFrame);
407 }
408
409 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
410 {
411     WebView* webView = m_webFrame->webView();
412     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
413     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
414         frameLoadDelegate->didStartProvisionalLoadForFrame(webView, m_webFrame);
415 }
416
417 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
418 {
419     WebView* webView = m_webFrame->webView();
420     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
421     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
422         // FIXME: use direction of title.
423         frameLoadDelegate->didReceiveTitle(webView, BString(title.string), m_webFrame);
424 }
425
426 void WebFrameLoaderClient::dispatchDidCommitLoad(std::optional<HasInsecureContent>)
427 {
428     WebView* webView = m_webFrame->webView();
429     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
430     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
431         frameLoadDelegate->didCommitLoadForFrame(webView, m_webFrame);
432 }
433
434 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
435 {
436     WebView* webView = m_webFrame->webView();
437     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
438     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) {
439         COMPtr<IWebError> webError;
440         webError.adoptRef(WebError::createInstance(error));
441         frameLoadDelegate->didFailProvisionalLoadWithError(webView, webError.get(), m_webFrame);
442     }
443 }
444
445 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
446 {
447     WebView* webView = m_webFrame->webView();
448     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
449     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) {
450         COMPtr<IWebError> webError;
451         webError.adoptRef(WebError::createInstance(error));
452         frameLoadDelegate->didFailLoadWithError(webView, webError.get(), m_webFrame);
453     }
454 }
455
456 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
457 {
458     WebView* webView = m_webFrame->webView();
459     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
460     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
461         frameLoadDelegatePriv->didFinishDocumentLoadForFrame(webView, m_webFrame);
462 }
463
464 void WebFrameLoaderClient::dispatchDidFinishLoad()
465 {
466     WebView* webView = m_webFrame->webView();
467     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
468     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
469         frameLoadDelegate->didFinishLoadForFrame(webView, m_webFrame);
470 }
471
472 void WebFrameLoaderClient::dispatchDidReachLayoutMilestone(LayoutMilestones milestones)
473 {
474     WebView* webView = m_webFrame->webView();
475
476     if (milestones & DidFirstLayout) {
477         COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePrivate;
478         if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate)
479             frameLoadDelegatePrivate->didFirstLayoutInFrame(webView, m_webFrame);
480     }
481
482     if (milestones & DidFirstVisuallyNonEmptyLayout) {
483         COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePrivate;
484         if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate)
485             frameLoadDelegatePrivate->didFirstVisuallyNonEmptyLayoutInFrame(webView, m_webFrame);
486     }
487 }
488
489 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction)
490 {
491     WebView* webView = m_webFrame->webView();
492
493     COMPtr<IWebUIDelegate> ui;
494     if (FAILED(webView->uiDelegate(&ui)))
495         return 0;
496
497     COMPtr<IWebView> newWebView;
498     COMPtr<WebMutableURLRequest> request = adoptCOM(WebMutableURLRequest::createInstance(ResourceRequest(navigationAction.url())));
499     if (FAILED(ui->createWebViewWithRequest(webView, request.get(), &newWebView)) || !newWebView)
500         return 0;
501
502     COMPtr<IWebFrame> mainFrame;
503     if (FAILED(newWebView->mainFrame(&mainFrame)))
504         return 0;
505
506     COMPtr<WebFrame> mainFrameImpl(Query, mainFrame);
507     return core(mainFrameImpl.get());
508 }
509
510 void WebFrameLoaderClient::dispatchShow()
511 {
512     WebView* webView = m_webFrame->webView();
513     COMPtr<IWebUIDelegate> ui;
514     if (SUCCEEDED(webView->uiDelegate(&ui)))
515         ui->webViewShow(webView);
516 }
517
518 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, FramePolicyFunction function)
519 {
520     WebView* webView = m_webFrame->webView();
521     Frame* coreFrame = core(m_webFrame);
522     ASSERT(coreFrame);
523
524     COMPtr<IWebPolicyDelegate> policyDelegate;
525     if (FAILED(webView->policyDelegate(&policyDelegate)))
526         policyDelegate = DefaultPolicyDelegate::sharedInstance();
527
528     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
529
530     if (SUCCEEDED(policyDelegate->decidePolicyForMIMEType(webView, BString(response.mimeType()), urlRequest.get(), m_webFrame, setUpPolicyListener(function).get())))
531         return;
532
533     function(PolicyUse);
534 }
535
536 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const NavigationAction& action, const ResourceRequest& request, FormState* formState, const String& frameName, FramePolicyFunction function)
537 {
538     WebView* webView = m_webFrame->webView();
539     Frame* coreFrame = core(m_webFrame);
540     ASSERT(coreFrame);
541
542     COMPtr<IWebPolicyDelegate> policyDelegate;
543     if (FAILED(webView->policyDelegate(&policyDelegate)))
544         policyDelegate = DefaultPolicyDelegate::sharedInstance();
545
546     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
547     COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, formState ? &formState->form() : nullptr, coreFrame));
548
549     if (SUCCEEDED(policyDelegate->decidePolicyForNewWindowAction(webView, actionInformation.get(), urlRequest.get(), BString(frameName), setUpPolicyListener(function).get())))
550         return;
551
552     function(PolicyUse);
553 }
554
555 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& action, const ResourceRequest& request, FormState* formState, FramePolicyFunction function)
556 {
557     WebView* webView = m_webFrame->webView();
558     Frame* coreFrame = core(m_webFrame);
559     ASSERT(coreFrame);
560
561     COMPtr<IWebPolicyDelegate> policyDelegate;
562     if (FAILED(webView->policyDelegate(&policyDelegate)))
563         policyDelegate = DefaultPolicyDelegate::sharedInstance();
564
565     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
566     COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, formState ? &formState->form() : nullptr, coreFrame));
567
568     if (SUCCEEDED(policyDelegate->decidePolicyForNavigationAction(webView, actionInformation.get(), urlRequest.get(), m_webFrame, setUpPolicyListener(function).get())))
569         return;
570
571     function(PolicyUse);
572 }
573
574 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
575 {
576     WebView* webView = m_webFrame->webView();
577     COMPtr<IWebPolicyDelegate> policyDelegate;
578     if (FAILED(webView->policyDelegate(&policyDelegate)))
579         policyDelegate = DefaultPolicyDelegate::sharedInstance();
580
581     COMPtr<IWebError> webError(AdoptCOM, WebError::createInstance(error));
582     policyDelegate->unableToImplementPolicyWithError(webView, webError.get(), m_webFrame);
583 }
584
585 void WebFrameLoaderClient::dispatchWillSendSubmitEvent(Ref<WebCore::FormState>&&)
586 {
587 }
588
589 void WebFrameLoaderClient::dispatchWillSubmitForm(FormState& formState, FramePolicyFunction function)
590 {
591     WebView* webView = m_webFrame->webView();
592     Frame* coreFrame = core(m_webFrame);
593     ASSERT(coreFrame);
594
595     COMPtr<IWebFormDelegate> formDelegate;
596
597     if (FAILED(webView->formDelegate(&formDelegate))) {
598         function(PolicyUse);
599         return;
600     }
601
602     COMPtr<IDOMElement> formElement(AdoptCOM, DOMElement::createInstance(&formState.form()));
603
604     HashMap<String, String> formValuesMap;
605     const StringPairVector& textFieldValues = formState.textFieldValues();
606     size_t size = textFieldValues.size();
607     for (size_t i = 0; i < size; ++i)
608         formValuesMap.add(textFieldValues[i].first, textFieldValues[i].second);
609
610     COMPtr<IPropertyBag> formValuesPropertyBag(AdoptCOM, COMPropertyBag<String>::createInstance(formValuesMap));
611
612     COMPtr<WebFrame> sourceFrame(kit(formState.sourceDocument().frame()));
613     if (SUCCEEDED(formDelegate->willSubmitForm(m_webFrame, sourceFrame.get(), formElement.get(), formValuesPropertyBag.get(), setUpPolicyListener(function).get())))
614         return;
615
616     // FIXME: Add a sane default implementation
617     function(PolicyUse);
618 }
619
620 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
621 {
622     if (!m_manualLoader)
623         return;
624
625     m_manualLoader->didFail(error);
626     m_manualLoader = 0;
627     m_hasSentResponseToPlugin = false;
628 }
629
630 void WebFrameLoaderClient::progressStarted(WebCore::Frame&)
631 {
632     static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
633     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
634     notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
635 }
636
637 void WebFrameLoaderClient::progressEstimateChanged(WebCore::Frame&)
638 {
639     static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
640     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
641     notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
642 }
643
644 void WebFrameLoaderClient::progressFinished(WebCore::Frame&)
645 {
646     static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
647     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
648     notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
649 }
650
651 void WebFrameLoaderClient::startDownload(const ResourceRequest& request, const String& /* suggestedName */)
652 {
653     m_webFrame->webView()->downloadURL(request.url());
654 }
655
656 void WebFrameLoaderClient::willChangeTitle(DocumentLoader*)
657 {
658     notImplemented();
659 }
660
661 void WebFrameLoaderClient::didChangeTitle(DocumentLoader*)
662 {
663     notImplemented();
664 }
665
666 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
667 {
668     if (!m_manualLoader)
669         loader->commitData(data, length);
670
671     // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
672     // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
673     Frame* coreFrame = core(m_webFrame);
674     if (coreFrame->document()->isMediaDocument())
675         loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
676
677     if (!m_manualLoader)
678         return;
679
680     if (!m_hasSentResponseToPlugin) {
681         m_manualLoader->didReceiveResponse(loader->response());
682         // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
683         // setting up this stream can cause the main document load to be cancelled, setting m_manualLoader
684         // to null
685         if (!m_manualLoader)
686             return;
687         m_hasSentResponseToPlugin = true;
688     }
689     m_manualLoader->didReceiveData(data, length);
690 }
691
692 void WebFrameLoaderClient::finishedLoading(DocumentLoader*)
693 {
694     if (!m_manualLoader)
695         return;
696
697     m_manualLoader->didFinishLoading();
698     m_manualLoader = 0;
699     m_hasSentResponseToPlugin = false;
700 }
701
702 void WebFrameLoaderClient::updateGlobalHistory()
703 {
704     DocumentLoader* loader = core(m_webFrame)->loader().documentLoader();
705     WebView* webView = m_webFrame->webView();
706     COMPtr<IWebHistoryDelegate> historyDelegate;
707     webView->historyDelegate(&historyDelegate);
708
709     if (historyDelegate) {
710         COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(loader->response()));
711         COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(loader->originalRequestCopy()));
712         
713         COMPtr<IWebNavigationData> navigationData(AdoptCOM, WebNavigationData::createInstance(
714             loader->urlForHistory(), loader->title().string, urlRequest.get(), urlResponse.get(), loader->substituteData().isValid(), loader->clientRedirectSourceForHistory()));
715
716         historyDelegate->didNavigateWithNavigationData(webView, navigationData.get(), m_webFrame);
717         return;
718     }
719
720     WebHistory* history = WebHistory::sharedHistory();
721     if (!history)
722         return;
723
724     history->visitedURL(loader->urlForHistory(), loader->title().string, loader->originalRequestCopy().httpMethod(), loader->urlForHistoryReflectsFailure(), !loader->clientRedirectSourceForHistory());
725 }
726
727 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
728 {
729     WebView* webView = m_webFrame->webView();
730     COMPtr<IWebHistoryDelegate> historyDelegate;
731     webView->historyDelegate(&historyDelegate);
732
733     WebHistory* history = WebHistory::sharedHistory();
734
735     DocumentLoader* loader = core(m_webFrame)->loader().documentLoader();
736     ASSERT(loader->unreachableURL().isEmpty());
737
738     if (!loader->clientRedirectSourceForHistory().isNull()) {
739         if (historyDelegate) {
740             BString sourceURL(loader->clientRedirectSourceForHistory());
741             BString destURL(loader->clientRedirectDestinationForHistory());
742             historyDelegate->didPerformClientRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
743         }
744     }
745
746     if (!loader->serverRedirectSourceForHistory().isNull()) {
747         if (historyDelegate) {
748             BString sourceURL(loader->serverRedirectSourceForHistory());
749             BString destURL(loader->serverRedirectDestinationForHistory());
750             historyDelegate->didPerformServerRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
751         }
752     }
753 }
754
755 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const
756 {
757     return true;
758 }
759
760 void WebFrameLoaderClient::updateGlobalHistoryItemForPage()
761 {
762     HistoryItem* historyItem = 0;
763     WebView* webView = m_webFrame->webView();
764
765     if (Page* page = webView->page()) {
766         if (!page->usesEphemeralSession())
767             historyItem = page->backForward().currentItem();
768     }
769
770     webView->setGlobalHistoryItem(historyItem);
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     IntRect logicalFrame(pixelRect);
989     logicalFrame.scale(1.0f / view->deviceScaleFactor());
990     core(m_webFrame)->createView(logicalFrame.size(), backgroundColor, transparent);
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, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
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         mimeType = mimeTypeFromURL(url);
1044
1045     if (mimeType.isEmpty()) {
1046         String decodedPath = decodeURLEscapeSequences(url.path());
1047         mimeType = PluginDatabase::installedPlugins()->MIMETypeForExtension(decodedPath.substring(decodedPath.reverseFind('.') + 1));
1048     }
1049
1050     if (mimeType.isEmpty())
1051         return ObjectContentType::Frame; // Go ahead and hope that we can display the content.
1052
1053     bool plugInSupportsMIMEType = PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType);
1054
1055     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1056         return WebCore::ObjectContentType::Image;
1057
1058     if (plugInSupportsMIMEType)
1059         return WebCore::ObjectContentType::PlugIn;
1060
1061     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1062         return WebCore::ObjectContentType::Frame;
1063
1064     return WebCore::ObjectContentType::None;
1065 }
1066
1067 void WebFrameLoaderClient::dispatchDidFailToStartPlugin(const PluginView* pluginView) const
1068 {
1069     WebView* webView = m_webFrame->webView();
1070
1071     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
1072     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
1073         return;
1074
1075     RetainPtr<CFMutableDictionaryRef> userInfo = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
1076
1077     Frame* frame = core(m_webFrame);
1078     ASSERT(frame == pluginView->parentFrame());
1079
1080     if (!pluginView->pluginsPage().isNull()) {
1081         URL pluginPageURL = frame->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(pluginView->pluginsPage()));
1082         if (pluginPageURL.protocolIsInHTTPFamily()) {
1083             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
1084             CFDictionarySetValue(userInfo.get(), key, pluginPageURL.string().createCFString().get());
1085         }
1086     }
1087
1088     if (!pluginView->mimeType().isNull()) {
1089         static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
1090         CFDictionarySetValue(userInfo.get(), key, pluginView->mimeType().createCFString().get());
1091     }
1092
1093     if (pluginView->plugin()) {
1094         String pluginName = pluginView->plugin()->name();
1095         if (!pluginName.isNull()) {
1096             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
1097             CFDictionarySetValue(userInfo.get(), key, pluginName.createCFString().get());
1098         }
1099     }
1100
1101     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
1102     userInfoBag->setDictionary(userInfo.get());
1103  
1104     int errorCode = 0;
1105     String description;
1106     switch (pluginView->status()) {
1107         case PluginStatusCanNotFindPlugin:
1108             errorCode = WebKitErrorCannotFindPlugIn;
1109             description = WEB_UI_STRING("The plug-in can\xE2\x80\x99t be found", "WebKitErrorCannotFindPlugin description");
1110             break;
1111         case PluginStatusCanNotLoadPlugin:
1112             errorCode = WebKitErrorCannotLoadPlugIn;
1113             description = WEB_UI_STRING("The plug-in can\xE2\x80\x99t be loaded", "WebKitErrorCannotLoadPlugin description");
1114             break;
1115         default:
1116             ASSERT_NOT_REACHED();
1117     }
1118
1119     ResourceError resourceError(String(WebKitErrorDomain), errorCode, pluginView->url(), String());
1120     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
1121      
1122     resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader().documentLoader()));
1123 }
1124
1125 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)
1126 {
1127     WebView* webView = m_webFrame->webView();
1128
1129     COMPtr<IWebUIDelegate> ui;
1130     if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) {
1131         COMPtr<IWebUIDelegatePrivate> uiPrivate(Query, ui);
1132
1133         if (uiPrivate) {
1134             // Assemble the view arguments in a property bag.
1135             HashMap<String, String> viewArguments;
1136             for (unsigned i = 0; i < paramNames.size(); i++) 
1137                 viewArguments.set(paramNames[i], paramValues[i]);
1138             COMPtr<IPropertyBag> viewArgumentsBag(AdoptCOM, COMPropertyBag<String>::adopt(viewArguments));
1139             COMPtr<IDOMElement> containingElement(AdoptCOM, DOMElement::createInstance(&element));
1140
1141             HashMap<String, COMVariant> arguments;
1142
1143             arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag);
1144             arguments.set(WebEmbeddedViewBaseURLKey, url.string());
1145             arguments.set(WebEmbeddedViewContainingElementKey, containingElement);
1146             arguments.set(WebEmbeddedViewMIMETypeKey, mimeType);
1147
1148             COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMVariant>::adopt(arguments));
1149
1150             COMPtr<IWebEmbeddedView> view;
1151             HRESULT result = uiPrivate->embeddedViewWithArguments(webView, m_webFrame, argumentsBag.get(), &view);
1152             if (SUCCEEDED(result)) {
1153                 HWND parentWindow;
1154                 HRESULT hr = webView->viewWindow(&parentWindow);
1155                 ASSERT(SUCCEEDED(hr));
1156
1157                 return EmbeddedWidget::create(view.get(), &element, parentWindow, pluginSize);
1158             }
1159         }
1160     }
1161
1162     Frame* frame = core(m_webFrame);
1163     RefPtr<PluginView> pluginView = PluginView::create(frame, pluginSize, &element, url, paramNames, paramValues, mimeType, loadManually);
1164
1165     if (pluginView->status() == PluginStatusLoadedSuccessfully)
1166         return pluginView;
1167
1168     dispatchDidFailToStartPlugin(pluginView.get());
1169
1170     return nullptr;
1171 }
1172
1173 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1174 {
1175     // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
1176     if (!pluginWidget || pluginWidget->isPluginView())
1177         m_manualLoader = toPluginView(pluginWidget);
1178     else 
1179         m_manualLoader = static_cast<EmbeddedWidget*>(pluginWidget);
1180 }
1181
1182 RefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement& element, const URL& /*baseURL*/, const Vector<String>& paramNames, const Vector<String>& paramValues)
1183 {
1184     RefPtr<PluginView> pluginView = PluginView::create(core(m_webFrame), pluginSize, &element, URL(), paramNames, paramValues, "application/x-java-applet", false);
1185
1186     // Check if the plugin can be loaded successfully
1187     if (pluginView->plugin() && pluginView->plugin()->load())
1188         return WTFMove(pluginView);
1189
1190     WebView* webView = m_webFrame->webView();
1191     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
1192     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
1193         return WTFMove(pluginView);
1194
1195     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
1196
1197     ResourceError resourceError(String(WebKitErrorDomain), WebKitErrorJavaUnavailable, URL(), WEB_UI_STRING("Java is unavailable", "WebKitErrorJavaUnavailable description"));
1198     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
1199
1200     Frame* coreFrame = core(m_webFrame);
1201     ASSERT(coreFrame);
1202
1203     resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(coreFrame->loader().documentLoader()));
1204
1205     return WTFMove(pluginView);
1206 }
1207
1208 WebHistory* WebFrameLoaderClient::webHistory() const
1209 {
1210     if (m_webFrame != m_webFrame->webView()->topLevelFrame())
1211         return 0;
1212
1213     return WebHistory::sharedHistory();
1214 }
1215
1216 String WebFrameLoaderClient::overrideMediaType() const
1217 {
1218     notImplemented();
1219     return String();
1220 }
1221
1222 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
1223 {
1224     Frame* coreFrame = core(m_webFrame);
1225     ASSERT(coreFrame);
1226
1227     if (!coreFrame->settings().isScriptEnabled())
1228         return;
1229
1230     WebView* webView = m_webFrame->webView();
1231     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1232     if (FAILED(webView->frameLoadDelegate(&frameLoadDelegate)))
1233         return;
1234
1235     COMPtr<IWebFrameLoadDelegatePrivate2> delegatePrivate(Query, frameLoadDelegate);
1236     if (delegatePrivate && delegatePrivate->didClearWindowObjectForFrameInScriptWorld(webView, m_webFrame, WebScriptWorld::findOrCreateWorld(world).get()) != E_NOTIMPL)
1237         return;
1238
1239     if (&world != &mainThreadNormalWorld())
1240         return;
1241
1242     JSContextRef context = toRef(coreFrame->script().globalObject(world)->globalExec());
1243     JSObjectRef windowObject = toRef(coreFrame->script().globalObject(world));
1244     ASSERT(windowObject);
1245
1246     if (FAILED(frameLoadDelegate->didClearWindowObject(webView, context, windowObject, m_webFrame)))
1247         frameLoadDelegate->windowScriptObjectAvailable(webView, context, windowObject);
1248 }
1249
1250 void WebFrameLoaderClient::registerForIconNotification(bool listen)
1251 {
1252     m_webFrame->webView()->registerForIconNotification(listen);
1253 }
1254
1255 Ref<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1256 {
1257     return WebFrameNetworkingContext::create(core(m_webFrame));
1258 }
1259
1260 bool WebFrameLoaderClient::shouldAlwaysUsePluginDocument(const String& mimeType) const
1261 {
1262     WebView* webView = m_webFrame->webView();
1263     if (!webView)
1264         return false;
1265
1266     return webView->shouldUseEmbeddedView(mimeType);
1267 }
1268
1269 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*)
1270 {
1271     notImplemented();
1272 }
1273
1274 void WebFrameLoaderClient::setMainFrameDocumentReady(bool)
1275 {
1276     notImplemented();
1277 }
1278
1279 void WebFrameLoaderClient::cancelPolicyCheck()
1280 {
1281     if (m_policyListenerPrivate->m_policyListener) {
1282         m_policyListenerPrivate->m_policyListener->invalidate();
1283         m_policyListenerPrivate->m_policyListener = 0;
1284     }
1285
1286     m_policyListenerPrivate->m_policyFunction = nullptr;
1287 }
1288
1289 COMPtr<WebFramePolicyListener> WebFrameLoaderClient::setUpPolicyListener(WebCore::FramePolicyFunction function)
1290 {
1291     // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
1292
1293     if (m_policyListenerPrivate->m_policyListener)
1294         m_policyListenerPrivate->m_policyListener->invalidate();
1295
1296     Frame* coreFrame = core(m_webFrame);
1297     ASSERT(coreFrame);
1298
1299     m_policyListenerPrivate->m_policyListener.adoptRef(WebFramePolicyListener::createInstance(coreFrame));
1300     m_policyListenerPrivate->m_policyFunction = function;
1301
1302     return m_policyListenerPrivate->m_policyListener;
1303 }
1304
1305 void WebFrameLoaderClient::receivedPolicyDecision(PolicyAction action)
1306 {
1307     ASSERT(m_policyListenerPrivate->m_policyListener);
1308     ASSERT(m_policyListenerPrivate->m_policyFunction);
1309
1310     FramePolicyFunction function = m_policyListenerPrivate->m_policyFunction;
1311
1312     m_policyListenerPrivate->m_policyListener = 0;
1313     m_policyListenerPrivate->m_policyFunction = nullptr;
1314
1315     Frame* coreFrame = core(m_webFrame);
1316     ASSERT(coreFrame);
1317
1318     function(action);
1319 }
1320
1321 void WebFrameLoaderClient::prefetchDNS(const String& hostname)
1322 {
1323     WebCore::prefetchDNS(hostname);
1324 }