[Content Filtering] Determine navigation and content policy before continuing to...
[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/ScriptController.h>
83 #include <WebCore/Settings.h>
84 #include <WebCore/SubresourceLoader.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.ptr()));
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 pixelRect;
1021     view->frameRect(&pixelRect);
1022     bool transparent = view->transparent();
1023     Color backgroundColor = transparent ? Color::transparent : Color::white;
1024     IntRect logicalFrame(pixelRect);
1025     logicalFrame.scale(1.0f / view->deviceScaleFactor());
1026     core(m_webFrame)->createView(logicalFrame.size(), backgroundColor, transparent);
1027 }
1028
1029 void WebFrameLoaderClient::didSaveToPageCache()
1030 {
1031 }
1032
1033 void WebFrameLoaderClient::didRestoreFromPageCache()
1034 {
1035 }
1036
1037 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool)
1038 {
1039 }
1040
1041 String WebFrameLoaderClient::userAgent(const URL& url)
1042 {
1043     return m_webFrame->webView()->userAgentForKURL(url);
1044 }
1045
1046 bool WebFrameLoaderClient::canCachePage() const
1047 {
1048     return true;
1049 }
1050
1051 RefPtr<Frame> WebFrameLoaderClient::createFrame(const URL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1052                             const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
1053 {
1054     RefPtr<Frame> result = createFrame(url, name, ownerElement, referrer);
1055     if (!result)
1056         return nullptr;
1057     return result;
1058 }
1059
1060 RefPtr<Frame> WebFrameLoaderClient::createFrame(const URL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
1061 {
1062     Frame* coreFrame = core(m_webFrame);
1063     ASSERT(coreFrame);
1064
1065     COMPtr<WebFrame> webFrame(AdoptCOM, WebFrame::createInstance());
1066
1067     RefPtr<Frame> childFrame = webFrame->createSubframeWithOwnerElement(m_webFrame->webView(), coreFrame->page(), ownerElement);
1068
1069     childFrame->tree().setName(name);
1070     coreFrame->tree().appendChild(childFrame);
1071     childFrame->init();
1072
1073     coreFrame->loader().loadURLIntoChildFrame(URL, referrer, childFrame.get());
1074
1075     // The frame's onload handler may have removed it from the document.
1076     if (!childFrame->tree().parent())
1077         return nullptr;
1078
1079     return childFrame;
1080 }
1081
1082 ObjectContentType WebFrameLoaderClient::objectContentType(const URL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
1083 {
1084     String mimeType = mimeTypeIn;
1085
1086     if (mimeType.isEmpty())
1087         mimeType = mimeTypeFromURL(url);
1088
1089     if (mimeType.isEmpty()) {
1090         String decodedPath = decodeURLEscapeSequences(url.path());
1091         mimeType = PluginDatabase::installedPlugins()->MIMETypeForExtension(decodedPath.substring(decodedPath.reverseFind('.') + 1));
1092     }
1093
1094     if (mimeType.isEmpty())
1095         return ObjectContentFrame; // Go ahead and hope that we can display the content.
1096
1097     bool plugInSupportsMIMEType = PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType);
1098
1099     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1100         return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? WebCore::ObjectContentNetscapePlugin : WebCore::ObjectContentImage;
1101
1102     if (plugInSupportsMIMEType)
1103         return WebCore::ObjectContentNetscapePlugin;
1104
1105     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1106         return WebCore::ObjectContentFrame;
1107
1108     return WebCore::ObjectContentNone;
1109 }
1110
1111 void WebFrameLoaderClient::dispatchDidFailToStartPlugin(const PluginView* pluginView) const
1112 {
1113     WebView* webView = m_webFrame->webView();
1114
1115     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
1116     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
1117         return;
1118
1119     RetainPtr<CFMutableDictionaryRef> userInfo = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
1120
1121     Frame* frame = core(m_webFrame);
1122     ASSERT(frame == pluginView->parentFrame());
1123
1124     if (!pluginView->pluginsPage().isNull()) {
1125         URL pluginPageURL = frame->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(pluginView->pluginsPage()));
1126         if (pluginPageURL.protocolIsInHTTPFamily()) {
1127             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
1128             CFDictionarySetValue(userInfo.get(), key, pluginPageURL.string().createCFString().get());
1129         }
1130     }
1131
1132     if (!pluginView->mimeType().isNull()) {
1133         static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
1134         CFDictionarySetValue(userInfo.get(), key, pluginView->mimeType().createCFString().get());
1135     }
1136
1137     if (pluginView->plugin()) {
1138         String pluginName = pluginView->plugin()->name();
1139         if (!pluginName.isNull()) {
1140             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
1141             CFDictionarySetValue(userInfo.get(), key, pluginName.createCFString().get());
1142         }
1143     }
1144
1145     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
1146     userInfoBag->setDictionary(userInfo.get());
1147  
1148     int errorCode = 0;
1149     String description;
1150     switch (pluginView->status()) {
1151         case PluginStatusCanNotFindPlugin:
1152             errorCode = WebKitErrorCannotFindPlugIn;
1153             description = WEB_UI_STRING("The plug-in can\xE2\x80\x99t be found", "WebKitErrorCannotFindPlugin description");
1154             break;
1155         case PluginStatusCanNotLoadPlugin:
1156             errorCode = WebKitErrorCannotLoadPlugIn;
1157             description = WEB_UI_STRING("The plug-in can\xE2\x80\x99t be loaded", "WebKitErrorCannotLoadPlugin description");
1158             break;
1159         default:
1160             ASSERT_NOT_REACHED();
1161     }
1162
1163     ResourceError resourceError(String(WebKitErrorDomain), errorCode, pluginView->url().string(), String());
1164     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
1165      
1166     resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader().documentLoader()));
1167 }
1168
1169 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)
1170 {
1171     WebView* webView = m_webFrame->webView();
1172
1173     COMPtr<IWebUIDelegate> ui;
1174     if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) {
1175         COMPtr<IWebUIDelegatePrivate> uiPrivate(Query, ui);
1176
1177         if (uiPrivate) {
1178             // Assemble the view arguments in a property bag.
1179             HashMap<String, String> viewArguments;
1180             for (unsigned i = 0; i < paramNames.size(); i++) 
1181                 viewArguments.set(paramNames[i], paramValues[i]);
1182             COMPtr<IPropertyBag> viewArgumentsBag(AdoptCOM, COMPropertyBag<String>::adopt(viewArguments));
1183             COMPtr<IDOMElement> containingElement(AdoptCOM, DOMElement::createInstance(element));
1184
1185             HashMap<String, COMVariant> arguments;
1186
1187             arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag);
1188             arguments.set(WebEmbeddedViewBaseURLKey, url.string());
1189             arguments.set(WebEmbeddedViewContainingElementKey, containingElement);
1190             arguments.set(WebEmbeddedViewMIMETypeKey, mimeType);
1191
1192             COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMVariant>::adopt(arguments));
1193
1194             COMPtr<IWebEmbeddedView> view;
1195             HRESULT result = uiPrivate->embeddedViewWithArguments(webView, m_webFrame, argumentsBag.get(), &view);
1196             if (SUCCEEDED(result)) {
1197                 HWND parentWindow;
1198                 HRESULT hr = webView->viewWindow(&parentWindow);
1199                 ASSERT(SUCCEEDED(hr));
1200
1201                 return EmbeddedWidget::create(view.get(), element, parentWindow, pluginSize);
1202             }
1203         }
1204     }
1205
1206     Frame* frame = core(m_webFrame);
1207     RefPtr<PluginView> pluginView = PluginView::create(frame, pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
1208
1209     if (pluginView->status() == PluginStatusLoadedSuccessfully)
1210         return pluginView;
1211
1212     dispatchDidFailToStartPlugin(pluginView.get());
1213
1214     return nullptr;
1215 }
1216
1217 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1218 {
1219     // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
1220     if (!pluginWidget || pluginWidget->isPluginView())
1221         m_manualLoader = toPluginView(pluginWidget);
1222     else 
1223         m_manualLoader = static_cast<EmbeddedWidget*>(pluginWidget);
1224 }
1225
1226 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* element, const URL& /*baseURL*/, const Vector<String>& paramNames, const Vector<String>& paramValues)
1227 {
1228     RefPtr<PluginView> pluginView = PluginView::create(core(m_webFrame), pluginSize, element, URL(), paramNames, paramValues, "application/x-java-applet", false);
1229
1230     // Check if the plugin can be loaded successfully
1231     if (pluginView->plugin() && pluginView->plugin()->load())
1232         return pluginView;
1233
1234     WebView* webView = m_webFrame->webView();
1235     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
1236     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
1237         return pluginView;
1238
1239     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
1240
1241     ResourceError resourceError(String(WebKitErrorDomain), WebKitErrorJavaUnavailable, String(), WEB_UI_STRING("Java is unavailable", "WebKitErrorJavaUnavailable description"));
1242     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
1243
1244     Frame* coreFrame = core(m_webFrame);
1245     ASSERT(coreFrame);
1246
1247     resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(coreFrame->loader().documentLoader()));
1248
1249     return pluginView;
1250 }
1251
1252 WebHistory* WebFrameLoaderClient::webHistory() const
1253 {
1254     if (m_webFrame != m_webFrame->webView()->topLevelFrame())
1255         return 0;
1256
1257     return WebHistory::sharedHistory();
1258 }
1259
1260 String WebFrameLoaderClient::overrideMediaType() const
1261 {
1262     notImplemented();
1263     return String();
1264 }
1265
1266 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
1267 {
1268     Frame* coreFrame = core(m_webFrame);
1269     ASSERT(coreFrame);
1270
1271     if (!coreFrame->settings().isScriptEnabled())
1272         return;
1273
1274     WebView* webView = m_webFrame->webView();
1275     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1276     if (FAILED(webView->frameLoadDelegate(&frameLoadDelegate)))
1277         return;
1278
1279     COMPtr<IWebFrameLoadDelegatePrivate2> delegatePrivate(Query, frameLoadDelegate);
1280     if (delegatePrivate && delegatePrivate->didClearWindowObjectForFrameInScriptWorld(webView, m_webFrame, WebScriptWorld::findOrCreateWorld(world).get()) != E_NOTIMPL)
1281         return;
1282
1283     if (&world != &mainThreadNormalWorld())
1284         return;
1285
1286     JSContextRef context = toRef(coreFrame->script().globalObject(world)->globalExec());
1287     JSObjectRef windowObject = toRef(coreFrame->script().globalObject(world));
1288     ASSERT(windowObject);
1289
1290     if (FAILED(frameLoadDelegate->didClearWindowObject(webView, context, windowObject, m_webFrame)))
1291         frameLoadDelegate->windowScriptObjectAvailable(webView, context, windowObject);
1292 }
1293
1294 void WebFrameLoaderClient::registerForIconNotification(bool listen)
1295 {
1296     m_webFrame->webView()->registerForIconNotification(listen);
1297 }
1298
1299 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1300 {
1301     return WebFrameNetworkingContext::create(core(m_webFrame));
1302 }
1303
1304 bool WebFrameLoaderClient::shouldAlwaysUsePluginDocument(const String& mimeType) const
1305 {
1306     WebView* webView = m_webFrame->webView();
1307     if (!webView)
1308         return false;
1309
1310     return webView->shouldUseEmbeddedView(mimeType);
1311 }
1312
1313 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*)
1314 {
1315     notImplemented();
1316 }
1317
1318 void WebFrameLoaderClient::setMainFrameDocumentReady(bool)
1319 {
1320     notImplemented();
1321 }
1322
1323 void WebFrameLoaderClient::cancelPolicyCheck()
1324 {
1325     if (m_policyListenerPrivate->m_policyListener) {
1326         m_policyListenerPrivate->m_policyListener->invalidate();
1327         m_policyListenerPrivate->m_policyListener = 0;
1328     }
1329
1330     m_policyListenerPrivate->m_policyFunction = nullptr;
1331 }
1332
1333 COMPtr<WebFramePolicyListener> WebFrameLoaderClient::setUpPolicyListener(WebCore::FramePolicyFunction function)
1334 {
1335     // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
1336
1337     if (m_policyListenerPrivate->m_policyListener)
1338         m_policyListenerPrivate->m_policyListener->invalidate();
1339
1340     Frame* coreFrame = core(m_webFrame);
1341     ASSERT(coreFrame);
1342
1343     m_policyListenerPrivate->m_policyListener.adoptRef(WebFramePolicyListener::createInstance(coreFrame));
1344     m_policyListenerPrivate->m_policyFunction = function;
1345
1346     return m_policyListenerPrivate->m_policyListener;
1347 }
1348
1349 void WebFrameLoaderClient::receivedPolicyDecision(PolicyAction action)
1350 {
1351     ASSERT(m_policyListenerPrivate->m_policyListener);
1352     ASSERT(m_policyListenerPrivate->m_policyFunction);
1353
1354     FramePolicyFunction function = m_policyListenerPrivate->m_policyFunction;
1355
1356     m_policyListenerPrivate->m_policyListener = 0;
1357     m_policyListenerPrivate->m_policyFunction = nullptr;
1358
1359     Frame* coreFrame = core(m_webFrame);
1360     ASSERT(coreFrame);
1361
1362     function(action);
1363 }