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