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