710fec29aa982b12a0a4dac39339df7bce07b51a
[WebKit.git] / Source / WebKit / win / WebCoreSupport / WebFrameLoaderClient.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009 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 "EmbeddedWidget.h"
36 #include "MarshallingHelpers.h"
37 #include "NotImplemented.h"
38 #include "WebCachedFramePlatformData.h"
39 #include "WebChromeClient.h"
40 #include "WebDocumentLoader.h"
41 #include "WebError.h"
42 #include "WebFrame.h"
43 #include "WebHistory.h"
44 #include "WebHistoryItem.h"
45 #include "WebMutableURLRequest.h"
46 #include "WebNavigationData.h"
47 #include "WebNotificationCenter.h"
48 #include "WebSecurityOrigin.h"
49 #include "WebURLAuthenticationChallenge.h"
50 #include "WebURLResponse.h"
51 #include "WebView.h"
52 #pragma warning(push, 0)
53 #include <WebCore/CachedFrame.h>
54 #include <WebCore/DocumentLoader.h>
55 #include <WebCore/FrameLoader.h>
56 #include <WebCore/FrameTree.h>
57 #include <WebCore/FrameView.h>
58 #include <WebCore/HTMLAppletElement.h>
59 #include <WebCore/HTMLFrameElement.h>
60 #include <WebCore/HTMLFrameOwnerElement.h>
61 #include <WebCore/HTMLNames.h>
62 #include <WebCore/HTMLParserIdioms.h>
63 #include <WebCore/HTMLPlugInElement.h>
64 #include <WebCore/HistoryItem.h>
65 #include <WebCore/Page.h>
66 #include <WebCore/PluginPackage.h>
67 #include <WebCore/PluginView.h>
68 #include <WebCore/RenderPart.h>
69 #include <WebCore/ResourceHandle.h>
70 #pragma warning(pop)
71
72 using namespace WebCore;
73 using namespace HTMLNames;
74
75 static WebDataSource* getWebDataSource(DocumentLoader* loader)
76 {
77     return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0;
78 }
79
80 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* webFrame)
81     : m_webFrame(webFrame)
82     , m_manualLoader(0) 
83     , m_hasSentResponseToPlugin(false) 
84 {
85     ASSERT_ARG(webFrame, webFrame);
86 }
87
88 WebFrameLoaderClient::~WebFrameLoaderClient()
89 {
90 }
91
92 bool WebFrameLoaderClient::hasWebView() const
93 {
94     return m_webFrame->webView();
95 }
96
97 void WebFrameLoaderClient::forceLayout()
98 {
99     Frame* frame = core(m_webFrame);
100     if (!frame)
101         return;
102
103     if (frame->document() && frame->document()->inPageCache())
104         return;
105
106     FrameView* view = frame->view();
107     if (!view)
108         return;
109
110     view->setNeedsLayout();
111     view->forceLayout(true);
112 }
113
114 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
115 {
116     WebView* webView = m_webFrame->webView();
117     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
118     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
119         return;
120
121     COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
122     resourceLoadDelegate->identifierForInitialRequest(webView, webURLRequest.get(), getWebDataSource(loader), identifier);
123 }
124
125 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader* loader, unsigned long identifier)
126 {
127     WebView* webView = m_webFrame->webView();
128     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
129     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
130         return true;
131
132     COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate;
133     if (FAILED(resourceLoadDelegate->QueryInterface(IID_IWebResourceLoadDelegatePrivate, reinterpret_cast<void**>(&resourceLoadDelegatePrivate))))
134         return true;
135
136     BOOL shouldUse;
137     if (SUCCEEDED(resourceLoadDelegatePrivate->shouldUseCredentialStorage(webView, identifier, getWebDataSource(loader), &shouldUse)))
138         return shouldUse;
139
140     return true;
141 }
142
143 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
144 {
145 #if USE(CFNETWORK)
146     ASSERT(challenge.authenticationClient());
147
148     WebView* webView = m_webFrame->webView();
149     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
150     if (SUCCEEDED(webView->resourceLoadDelegate(&resourceLoadDelegate))) {
151         COMPtr<WebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
152         if (SUCCEEDED(resourceLoadDelegate->didReceiveAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader))))
153             return;
154     }
155
156     // If the ResourceLoadDelegate doesn't exist or fails to handle the call, we tell the ResourceHandle
157     // to continue without credential - this is the best approximation of Mac behavior
158     challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge);
159 #else
160    notImplemented();
161 #endif
162 }
163
164 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
165 {
166     WebView* webView = m_webFrame->webView();
167     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
168     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
169         return;
170
171     COMPtr<WebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
172     resourceLoadDelegate->didCancelAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader));
173 }
174
175 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
176 {
177     WebView* webView = m_webFrame->webView();
178     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
179     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
180         return;
181
182     COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
183     COMPtr<WebURLResponse> webURLRedirectResponse(AdoptCOM, WebURLResponse::createInstance(redirectResponse));
184
185     COMPtr<IWebURLRequest> newWebURLRequest;
186     if (FAILED(resourceLoadDelegate->willSendRequest(webView, identifier, webURLRequest.get(), webURLRedirectResponse.get(), getWebDataSource(loader), &newWebURLRequest)))
187         return;
188
189     if (webURLRequest == newWebURLRequest)
190         return;
191
192     if (!newWebURLRequest) {
193         request = ResourceRequest();
194         return;
195     }
196
197     COMPtr<WebMutableURLRequest> newWebURLRequestImpl(Query, newWebURLRequest);
198     if (!newWebURLRequestImpl)
199         return;
200
201     request = newWebURLRequestImpl->resourceRequest();
202 }
203
204 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
205 {
206     WebView* webView = m_webFrame->webView();
207     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
208     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
209         return;
210
211     COMPtr<WebURLResponse> webURLResponse(AdoptCOM, WebURLResponse::createInstance(response));
212     resourceLoadDelegate->didReceiveResponse(webView, identifier, webURLResponse.get(), getWebDataSource(loader));
213 }
214
215 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length)
216 {
217     WebView* webView = m_webFrame->webView();
218     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
219     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
220         return;
221
222     resourceLoadDelegate->didReceiveContentLength(webView, identifier, length, getWebDataSource(loader));
223 }
224
225 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
226 {
227     WebView* webView = m_webFrame->webView();
228     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
229     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
230         return;
231
232     resourceLoadDelegate->didFinishLoadingFromDataSource(webView, identifier, getWebDataSource(loader));
233 }
234
235 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
236 {
237     WebView* webView = m_webFrame->webView();
238     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
239     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
240         return;
241
242     COMPtr<WebError> webError(AdoptCOM, WebError::createInstance(error));
243     resourceLoadDelegate->didFailLoadingWithError(webView, identifier, webError.get(), getWebDataSource(loader));
244 }
245
246 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, const unsigned char* data, const unsigned long long length)
247 {
248     WebView* webView = m_webFrame->webView();
249     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
250     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
251         return true;
252
253     COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate(Query, resourceLoadDelegate);
254     if (!resourceLoadDelegatePrivate)
255         return true;
256
257     COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(response));
258     BOOL shouldCache;
259     if (SUCCEEDED(resourceLoadDelegatePrivate->shouldCacheResponse(webView, identifier, urlResponse.get(), data, length, getWebDataSource(loader), &shouldCache)))
260         return shouldCache;
261
262     return true;
263 }
264
265 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
266 {
267     WebView* webView = m_webFrame->webView();
268     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
269     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
270         frameLoadDelegatePriv->didHandleOnloadEventsForFrame(webView, m_webFrame);
271 }
272
273 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
274 {
275     WebView* webView = m_webFrame->webView();
276     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
277     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
278         frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(webView, m_webFrame);
279 }
280
281 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
282 {
283     WebView* webView = m_webFrame->webView();
284     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
285     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
286         frameLoadDelegate->didCancelClientRedirectForFrame(webView, m_webFrame);
287 }
288
289 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
290 {
291     WebView* webView = m_webFrame->webView();
292     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
293     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
294         frameLoadDelegate->willPerformClientRedirectToURL(webView, BString(url.string()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), m_webFrame);
295 }
296
297 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
298 {
299     WebView* webView = m_webFrame->webView();
300     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
301     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
302         frameLoadDelegate->didChangeLocationWithinPageForFrame(webView, m_webFrame);
303 }
304
305 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
306 {
307     WebView* webView = m_webFrame->webView();
308     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
309     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
310         return;
311
312     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
313     if (!frameLoadDelegatePriv2)
314         return;
315
316     frameLoadDelegatePriv2->didPushStateWithinPageForFrame(webView, m_webFrame);
317 }
318
319 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
320 {
321     WebView* webView = m_webFrame->webView();
322     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
323     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
324         return;
325
326     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
327     if (!frameLoadDelegatePriv2)
328         return;
329
330     frameLoadDelegatePriv2->didReplaceStateWithinPageForFrame(webView, m_webFrame);
331 }
332
333 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
334 {
335     WebView* webView = m_webFrame->webView();
336     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
337     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
338         return;
339
340     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
341     if (!frameLoadDelegatePriv2)
342         return;
343
344     frameLoadDelegatePriv2->didPopStateWithinPageForFrame(webView, m_webFrame);
345 }
346 void WebFrameLoaderClient::dispatchWillClose()
347 {
348     WebView* webView = m_webFrame->webView();
349     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
350     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
351         frameLoadDelegate->willCloseFrame(webView, m_webFrame);
352 }
353
354 void WebFrameLoaderClient::dispatchDidReceiveIcon()
355 {
356     m_webFrame->webView()->dispatchDidReceiveIconFromWebFrame(m_webFrame);
357 }
358
359 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
360 {
361     WebView* webView = m_webFrame->webView();
362     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
363     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
364         frameLoadDelegate->didStartProvisionalLoadForFrame(webView, m_webFrame);
365 }
366
367 void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title)
368 {
369     WebView* webView = m_webFrame->webView();
370     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
371     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
372         frameLoadDelegate->didReceiveTitle(webView, BString(title), m_webFrame);
373 }
374
375 void WebFrameLoaderClient::dispatchDidChangeIcons()
376 {
377     WebView* webView = m_webFrame->webView();
378     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
379     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
380         return;
381
382     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
383     if (!frameLoadDelegatePriv2)
384         return;
385
386     frameLoadDelegatePriv2->didChangeIcons(webView, m_webFrame);
387 }
388
389 void WebFrameLoaderClient::dispatchDidCommitLoad()
390 {
391     WebView* webView = m_webFrame->webView();
392     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
393     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
394         frameLoadDelegate->didCommitLoadForFrame(webView, m_webFrame);
395 }
396
397 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
398 {
399     WebView* webView = m_webFrame->webView();
400     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
401     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
402         frameLoadDelegatePriv->didFinishDocumentLoadForFrame(webView, m_webFrame);
403 }
404
405 void WebFrameLoaderClient::dispatchDidFinishLoad()
406 {
407     WebView* webView = m_webFrame->webView();
408     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
409     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
410         frameLoadDelegate->didFinishLoadForFrame(webView, m_webFrame);
411 }
412
413 void WebFrameLoaderClient::dispatchDidFirstLayout()
414 {
415     WebView* webView = m_webFrame->webView();
416     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
417     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
418         frameLoadDelegatePriv->didFirstLayoutInFrame(webView, m_webFrame);
419 }
420
421 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
422 {
423     WebView* webView = m_webFrame->webView();
424     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePrivate;
425     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate)
426         frameLoadDelegatePrivate->didFirstVisuallyNonEmptyLayoutInFrame(webView, m_webFrame);
427 }
428
429 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction&)
430 {
431     WebView* webView = m_webFrame->webView();
432
433     COMPtr<IWebUIDelegate> ui;
434     if (FAILED(webView->uiDelegate(&ui)))
435         return 0;
436
437     COMPtr<IWebView> newWebView;
438     if (FAILED(ui->createWebViewWithRequest(webView, 0, &newWebView)))
439         return 0;
440
441     COMPtr<IWebFrame> mainFrame;
442     if (FAILED(newWebView->mainFrame(&mainFrame)))
443         return 0;
444
445     COMPtr<WebFrame> mainFrameImpl(Query, mainFrame);
446     return core(mainFrameImpl.get());
447 }
448
449 void WebFrameLoaderClient::dispatchShow()
450 {
451     WebView* webView = m_webFrame->webView();
452     COMPtr<IWebUIDelegate> ui;
453     if (SUCCEEDED(webView->uiDelegate(&ui)))
454         ui->webViewShow(webView);
455 }
456
457 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
458 {
459 }
460
461 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
462 {
463     if (!m_manualLoader)
464         return;
465
466     m_manualLoader->didFail(error);
467     m_manualLoader = 0;
468     m_hasSentResponseToPlugin = false;
469 }
470
471 void WebFrameLoaderClient::postProgressStartedNotification()
472 {
473     static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
474     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
475     notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
476 }
477
478 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
479 {
480     static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
481     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
482     notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
483 }
484
485 void WebFrameLoaderClient::postProgressFinishedNotification()
486 {
487     static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
488     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
489     notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
490 }
491
492 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
493 {
494     if (!m_manualLoader)
495         loader->commitData(data, length);
496
497     // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
498     // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
499     Frame* coreFrame = core(m_webFrame);
500     if (coreFrame->document()->isMediaDocument())
501         loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
502
503     if (!m_manualLoader)
504         return;
505
506     if (!m_hasSentResponseToPlugin) {
507         m_manualLoader->didReceiveResponse(loader->response());
508         // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
509         // setting up this stream can cause the main document load to be cancelled, setting m_manualLoader
510         // to null
511         if (!m_manualLoader)
512             return;
513         m_hasSentResponseToPlugin = true;
514     }
515     m_manualLoader->didReceiveData(data, length);
516 }
517
518 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
519 {
520     // Telling the frame we received some data and passing 0 as the data is our
521     // way to get work done that is normally done when the first bit of data is
522     // received, even for the case of a document with no data (like about:blank)
523     committedLoad(loader, 0, 0);
524
525     if (!m_manualLoader)
526         return;
527
528     m_manualLoader->didFinishLoading();
529     m_manualLoader = 0;
530     m_hasSentResponseToPlugin = false;
531 }
532
533 void WebFrameLoaderClient::updateGlobalHistory()
534 {
535     DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
536     WebView* webView = m_webFrame->webView();
537     COMPtr<IWebHistoryDelegate> historyDelegate;
538     webView->historyDelegate(&historyDelegate);
539
540     if (historyDelegate) {
541         COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(loader->response()));
542         COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(loader->originalRequestCopy()));
543         
544         COMPtr<IWebNavigationData> navigationData(AdoptCOM, WebNavigationData::createInstance(
545             loader->urlForHistory(), loader->title(), urlRequest.get(), urlResponse.get(), loader->substituteData().isValid(), loader->clientRedirectSourceForHistory()));
546
547         historyDelegate->didNavigateWithNavigationData(webView, navigationData.get(), m_webFrame);
548         return;
549     }
550
551     WebHistory* history = WebHistory::sharedHistory();
552     if (!history)
553         return;
554
555     history->visitedURL(loader->urlForHistory(), loader->title(), loader->originalRequestCopy().httpMethod(), loader->urlForHistoryReflectsFailure(), !loader->clientRedirectSourceForHistory());
556 }
557
558 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
559 {
560     WebView* webView = m_webFrame->webView();
561     COMPtr<IWebHistoryDelegate> historyDelegate;
562     webView->historyDelegate(&historyDelegate);
563
564     WebHistory* history = WebHistory::sharedHistory();
565
566     DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
567     ASSERT(loader->unreachableURL().isEmpty());
568
569     if (!loader->clientRedirectSourceForHistory().isNull()) {
570         if (historyDelegate) {
571             BString sourceURL(loader->clientRedirectSourceForHistory());
572             BString destURL(loader->clientRedirectDestinationForHistory());
573             historyDelegate->didPerformClientRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
574         } else {
575             if (history) {
576                 if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->clientRedirectSourceForHistory())) {
577                     COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
578                     webHistoryItem->historyItem()->addRedirectURL(loader->clientRedirectDestinationForHistory());
579                 }
580             }
581         }
582     }
583
584     if (!loader->serverRedirectSourceForHistory().isNull()) {
585         if (historyDelegate) {
586             BString sourceURL(loader->serverRedirectSourceForHistory());
587             BString destURL(loader->serverRedirectDestinationForHistory());
588             historyDelegate->didPerformServerRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
589         } else {
590             if (history) {
591                 if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->serverRedirectSourceForHistory())) {
592                     COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
593                     webHistoryItem->historyItem()->addRedirectURL(loader->serverRedirectDestinationForHistory());
594                 }
595             }
596         }
597     }
598 }
599
600 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const
601 {
602     return true;
603 }
604
605 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
606 {
607 }
608
609 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const
610 {
611 }
612
613 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const
614 {
615 }
616
617 void WebFrameLoaderClient::didDisplayInsecureContent()
618 {
619     WebView* webView = m_webFrame->webView();
620     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
621     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
622         return;
623
624     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
625     if (!frameLoadDelegatePriv2)
626         return;
627
628     frameLoadDelegatePriv2->didDisplayInsecureContent(webView);
629 }
630
631 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin, const KURL& insecureURL)
632 {
633     COMPtr<IWebSecurityOrigin> webSecurityOrigin = WebSecurityOrigin::createInstance(origin);
634
635     WebView* webView = m_webFrame->webView();
636     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
637     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
638         return;
639
640     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
641     if (!frameLoadDelegatePriv2)
642         return;
643
644     frameLoadDelegatePriv2->didRunInsecureContent(webView, webSecurityOrigin.get());
645 }
646
647 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
648 {
649     RefPtr<WebDocumentLoader> loader = WebDocumentLoader::create(request, substituteData);
650
651     COMPtr<WebDataSource> dataSource(AdoptCOM, WebDataSource::createInstance(loader.get()));
652
653     loader->setDataSource(dataSource.get());
654     return loader.release();
655 }
656
657 void WebFrameLoaderClient::setTitle(const String& title, const KURL& url)
658 {
659     WebView* webView = m_webFrame->webView();
660     COMPtr<IWebHistoryDelegate> historyDelegate;
661     webView->historyDelegate(&historyDelegate);
662     if (historyDelegate) {
663         BString titleBSTR(title);
664         BString urlBSTR(url.string());
665         historyDelegate->updateHistoryTitle(webView, titleBSTR, urlBSTR);
666         return;
667     }
668
669     BOOL privateBrowsingEnabled = FALSE;
670     COMPtr<IWebPreferences> preferences;
671     if (SUCCEEDED(m_webFrame->webView()->preferences(&preferences)))
672         preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
673     if (privateBrowsingEnabled)
674         return;
675
676     // update title in global history
677     COMPtr<WebHistory> history = webHistory();
678     if (!history)
679         return;
680
681     COMPtr<IWebHistoryItem> item;
682     if (FAILED(history->itemForURL(BString(url.string()), &item)))
683         return;
684
685     COMPtr<IWebHistoryItemPrivate> itemPrivate(Query, item);
686     if (!itemPrivate)
687         return;
688
689     itemPrivate->setTitle(BString(title));
690 }
691
692 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
693 {
694 #if USE(CFNETWORK)
695     Frame* coreFrame = core(m_webFrame);
696     if (!coreFrame)
697         return;
698
699     ASSERT(coreFrame->loader()->documentLoader() == cachedFrame->documentLoader());
700
701     WebCachedFramePlatformData* webPlatformData = new WebCachedFramePlatformData(static_cast<IWebDataSource*>(getWebDataSource(coreFrame->loader()->documentLoader())));
702     cachedFrame->setCachedFramePlatformData(webPlatformData);
703 #else
704     notImplemented();
705 #endif
706 }
707
708 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
709 {
710 }
711
712 void WebFrameLoaderClient::transitionToCommittedForNewPage()
713 {
714     WebView* view = m_webFrame->webView();
715
716     RECT rect;
717     view->frameRect(&rect);
718     bool transparent = view->transparent();
719     Color backgroundColor = transparent ? Color::transparent : Color::white;
720     core(m_webFrame)->createView(IntRect(rect).size(), backgroundColor, transparent, IntSize(), false);
721 }
722
723 void WebFrameLoaderClient::didSaveToPageCache()
724 {
725 }
726
727 void WebFrameLoaderClient::didRestoreFromPageCache()
728 {
729 }
730
731 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool)
732 {
733 }
734
735 bool WebFrameLoaderClient::canCachePage() const
736 {
737     return true;
738 }
739
740 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
741                             const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
742 {
743     RefPtr<Frame> result = createFrame(url, name, ownerElement, referrer);
744     if (!result)
745         return 0;
746     return result.release();
747 }
748
749 void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*)
750 {
751     Frame* coreFrame = core(m_webFrame);
752     ASSERT(coreFrame);
753     WebView* webView = kit(coreFrame->page());
754     if (m_webFrame->webView() != webView)
755         m_webFrame->setWebView(webView);
756 }
757
758 void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request, Page* oldPage)
759 {
760     assignIdentifierToInitialRequest(identifier, loader, request);
761
762     WebView* oldWebView = kit(oldPage);
763     if (!oldWebView)
764         return;
765
766     COMPtr<IWebResourceLoadDelegate> oldResourceLoadDelegate;
767     if (FAILED(oldWebView->resourceLoadDelegate(&oldResourceLoadDelegate)))
768         return;
769
770     COMPtr<IWebResourceLoadDelegatePrivate2> oldResourceLoadDelegatePrivate2(Query, oldResourceLoadDelegate);
771     if (!oldResourceLoadDelegatePrivate2)
772         return;
773     oldResourceLoadDelegatePrivate2->removeIdentifierForRequest(oldWebView, identifier);
774 }
775
776 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
777 {
778     Frame* coreFrame = core(m_webFrame);
779     ASSERT(coreFrame);
780
781     COMPtr<WebFrame> webFrame(AdoptCOM, WebFrame::createInstance());
782
783     RefPtr<Frame> childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement);
784
785     childFrame->tree()->setName(name);
786     coreFrame->tree()->appendChild(childFrame);
787     childFrame->init();
788
789     coreFrame->loader()->loadURLIntoChildFrame(URL, referrer, childFrame.get());
790
791     // The frame's onload handler may have removed it from the document.
792     if (!childFrame->tree()->parent())
793         return 0;
794
795     return childFrame.release();
796 }
797
798 void WebFrameLoaderClient::dispatchDidFailToStartPlugin(const PluginView* pluginView) const
799 {
800     WebView* webView = m_webFrame->webView();
801
802     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
803     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
804         return;
805
806     RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
807
808     Frame* frame = core(m_webFrame);
809     ASSERT(frame == pluginView->parentFrame());
810
811     if (!pluginView->pluginsPage().isNull()) {
812         KURL pluginPageURL = frame->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(pluginView->pluginsPage()));
813         if (pluginPageURL.protocolInHTTPFamily()) {
814             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
815             RetainPtr<CFStringRef> str(AdoptCF, pluginPageURL.string().createCFString());
816             CFDictionarySetValue(userInfo.get(), key, str.get());
817         }
818     }
819
820     if (!pluginView->mimeType().isNull()) {
821         static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
822
823         RetainPtr<CFStringRef> str(AdoptCF, pluginView->mimeType().createCFString());
824         CFDictionarySetValue(userInfo.get(), key, str.get());
825     }
826
827     if (pluginView->plugin()) {
828         String pluginName = pluginView->plugin()->name();
829         if (!pluginName.isNull()) {
830             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
831             RetainPtr<CFStringRef> str(AdoptCF, pluginName.createCFString());
832             CFDictionarySetValue(userInfo.get(), key, str.get());
833         }
834     }
835
836     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
837     userInfoBag->setDictionary(userInfo.get());
838  
839     int errorCode = 0;
840     switch (pluginView->status()) {
841         case PluginStatusCanNotFindPlugin:
842             errorCode = WebKitErrorCannotFindPlugIn;
843             break;
844         case PluginStatusCanNotLoadPlugin:
845             errorCode = WebKitErrorCannotLoadPlugIn;
846             break;
847         default:
848             ASSERT_NOT_REACHED();
849     }
850
851     ResourceError resourceError(String(WebKitErrorDomain), errorCode, pluginView->url().string(), String());
852     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
853      
854     resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader()->documentLoader()));
855 }
856
857 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
858 {
859     WebView* webView = m_webFrame->webView();
860
861     COMPtr<IWebUIDelegate> ui;
862     if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) {
863         COMPtr<IWebUIDelegatePrivate> uiPrivate(Query, ui);
864
865         if (uiPrivate) {
866             // Assemble the view arguments in a property bag.
867             HashMap<String, String> viewArguments;
868             for (unsigned i = 0; i < paramNames.size(); i++) 
869                 viewArguments.set(paramNames[i], paramValues[i]);
870             COMPtr<IPropertyBag> viewArgumentsBag(AdoptCOM, COMPropertyBag<String>::adopt(viewArguments));
871             COMPtr<IDOMElement> containingElement(AdoptCOM, DOMElement::createInstance(element));
872
873             HashMap<String, COMVariant> arguments;
874
875             arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag);
876             arguments.set(WebEmbeddedViewBaseURLKey, url.string());
877             arguments.set(WebEmbeddedViewContainingElementKey, containingElement);
878             arguments.set(WebEmbeddedViewMIMETypeKey, mimeType);
879
880             COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMVariant>::adopt(arguments));
881
882             COMPtr<IWebEmbeddedView> view;
883             HRESULT result = uiPrivate->embeddedViewWithArguments(webView, m_webFrame, argumentsBag.get(), &view);
884             if (SUCCEEDED(result)) {
885                 HWND parentWindow;
886                 HRESULT hr = webView->viewWindow((OLE_HANDLE*)&parentWindow);
887                 ASSERT(SUCCEEDED(hr));
888
889                 return EmbeddedWidget::create(view.get(), element, parentWindow, pluginSize);
890             }
891         }
892     }
893
894     Frame* frame = core(m_webFrame);
895     RefPtr<PluginView> pluginView = PluginView::create(frame, pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
896
897     if (pluginView->status() == PluginStatusLoadedSuccessfully)
898         return pluginView;
899
900     dispatchDidFailToStartPlugin(pluginView.get());
901
902     return 0;
903 }
904
905 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
906 {
907     // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
908
909     if (pluginWidget->isPluginView())
910         m_manualLoader = static_cast<PluginView*>(pluginWidget);
911     else 
912         m_manualLoader = static_cast<EmbeddedWidget*>(pluginWidget);
913 }
914
915 WebHistory* WebFrameLoaderClient::webHistory() const
916 {
917     if (m_webFrame != m_webFrame->webView()->topLevelFrame())
918         return 0;
919
920     return WebHistory::sharedHistory();
921 }
922
923 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& mimeType) const
924 {
925     WebView* webView = m_webFrame->webView();
926     if (!webView)
927         return false;
928
929     return webView->shouldUseEmbeddedView(mimeType);
930 }