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