• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <WebCore/BackForwardController.h>
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 #include <WebCore/Settings.h>
71 
72 using namespace WebCore;
73 using namespace HTMLNames;
74 
getWebDataSource(DocumentLoader * loader)75 static WebDataSource* getWebDataSource(DocumentLoader* loader)
76 {
77     return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0;
78 }
79 
WebFrameLoaderClient(WebFrame * webFrame)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 
~WebFrameLoaderClient()88 WebFrameLoaderClient::~WebFrameLoaderClient()
89 {
90 }
91 
hasWebView() const92 bool WebFrameLoaderClient::hasWebView() const
93 {
94     return m_webFrame->webView();
95 }
96 
forceLayout()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 
assignIdentifierToInitialRequest(unsigned long identifier,DocumentLoader * loader,const ResourceRequest & request)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 
shouldUseCredentialStorage(DocumentLoader * loader,unsigned long identifier)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 
dispatchDidReceiveAuthenticationChallenge(DocumentLoader * loader,unsigned long identifier,const AuthenticationChallenge & challenge)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 
dispatchDidCancelAuthenticationChallenge(DocumentLoader * loader,unsigned long identifier,const AuthenticationChallenge & challenge)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 
dispatchWillSendRequest(DocumentLoader * loader,unsigned long identifier,ResourceRequest & request,const ResourceResponse & redirectResponse)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 
dispatchDidReceiveResponse(DocumentLoader * loader,unsigned long identifier,const ResourceResponse & response)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 
dispatchDidReceiveContentLength(DocumentLoader * loader,unsigned long identifier,int length)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 
dispatchDidFinishLoading(DocumentLoader * loader,unsigned long identifier)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 
dispatchDidFailLoading(DocumentLoader * loader,unsigned long identifier,const ResourceError & error)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 
shouldCacheResponse(DocumentLoader * loader,unsigned long identifier,const ResourceResponse & response,const unsigned char * data,const unsigned long long length)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 
dispatchDidHandleOnloadEvents()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 
dispatchDidReceiveServerRedirectForProvisionalLoad()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 
dispatchDidCancelClientRedirect()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 
dispatchWillPerformClientRedirect(const KURL & url,double delay,double fireDate)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 
dispatchDidChangeLocationWithinPage()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 
dispatchDidPushStateWithinPage()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 
dispatchDidReplaceStateWithinPage()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 
dispatchDidPopStateWithinPage()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 }
dispatchWillClose()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 
dispatchDidReceiveIcon()354 void WebFrameLoaderClient::dispatchDidReceiveIcon()
355 {
356     m_webFrame->webView()->dispatchDidReceiveIconFromWebFrame(m_webFrame);
357 }
358 
dispatchDidStartProvisionalLoad()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 
dispatchDidReceiveTitle(const StringWithDirection & title)367 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
368 {
369     WebView* webView = m_webFrame->webView();
370     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
371     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
372         // FIXME: use direction of title.
373         frameLoadDelegate->didReceiveTitle(webView, BString(title.string()), m_webFrame);
374 }
375 
dispatchDidChangeIcons()376 void WebFrameLoaderClient::dispatchDidChangeIcons()
377 {
378     WebView* webView = m_webFrame->webView();
379     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
380     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
381         return;
382 
383     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
384     if (!frameLoadDelegatePriv2)
385         return;
386 
387     frameLoadDelegatePriv2->didChangeIcons(webView, m_webFrame);
388 }
389 
dispatchDidCommitLoad()390 void WebFrameLoaderClient::dispatchDidCommitLoad()
391 {
392     WebView* webView = m_webFrame->webView();
393     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
394     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
395         frameLoadDelegate->didCommitLoadForFrame(webView, m_webFrame);
396 }
397 
dispatchDidFinishDocumentLoad()398 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
399 {
400     WebView* webView = m_webFrame->webView();
401     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
402     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
403         frameLoadDelegatePriv->didFinishDocumentLoadForFrame(webView, m_webFrame);
404 }
405 
dispatchDidFinishLoad()406 void WebFrameLoaderClient::dispatchDidFinishLoad()
407 {
408     WebView* webView = m_webFrame->webView();
409     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
410     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
411         frameLoadDelegate->didFinishLoadForFrame(webView, m_webFrame);
412 }
413 
dispatchDidFirstLayout()414 void WebFrameLoaderClient::dispatchDidFirstLayout()
415 {
416     WebView* webView = m_webFrame->webView();
417     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
418     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
419         frameLoadDelegatePriv->didFirstLayoutInFrame(webView, m_webFrame);
420 }
421 
dispatchDidFirstVisuallyNonEmptyLayout()422 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
423 {
424     WebView* webView = m_webFrame->webView();
425     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePrivate;
426     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate)
427         frameLoadDelegatePrivate->didFirstVisuallyNonEmptyLayoutInFrame(webView, m_webFrame);
428 }
429 
dispatchCreatePage(const NavigationAction &)430 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction&)
431 {
432     WebView* webView = m_webFrame->webView();
433 
434     COMPtr<IWebUIDelegate> ui;
435     if (FAILED(webView->uiDelegate(&ui)))
436         return 0;
437 
438     COMPtr<IWebView> newWebView;
439     if (FAILED(ui->createWebViewWithRequest(webView, 0, &newWebView)))
440         return 0;
441 
442     COMPtr<IWebFrame> mainFrame;
443     if (FAILED(newWebView->mainFrame(&mainFrame)))
444         return 0;
445 
446     COMPtr<WebFrame> mainFrameImpl(Query, mainFrame);
447     return core(mainFrameImpl.get());
448 }
449 
dispatchShow()450 void WebFrameLoaderClient::dispatchShow()
451 {
452     WebView* webView = m_webFrame->webView();
453     COMPtr<IWebUIDelegate> ui;
454     if (SUCCEEDED(webView->uiDelegate(&ui)))
455         ui->webViewShow(webView);
456 }
457 
dispatchDidLoadMainResource(DocumentLoader *)458 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
459 {
460 }
461 
setMainDocumentError(DocumentLoader *,const ResourceError & error)462 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
463 {
464     if (!m_manualLoader)
465         return;
466 
467     m_manualLoader->didFail(error);
468     m_manualLoader = 0;
469     m_hasSentResponseToPlugin = false;
470 }
471 
postProgressStartedNotification()472 void WebFrameLoaderClient::postProgressStartedNotification()
473 {
474     static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
475     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
476     notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
477 }
478 
postProgressEstimateChangedNotification()479 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
480 {
481     static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
482     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
483     notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
484 }
485 
postProgressFinishedNotification()486 void WebFrameLoaderClient::postProgressFinishedNotification()
487 {
488     static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
489     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
490     notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
491 }
492 
committedLoad(DocumentLoader * loader,const char * data,int length)493 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
494 {
495     if (!m_manualLoader)
496         loader->commitData(data, length);
497 
498     // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
499     // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
500     Frame* coreFrame = core(m_webFrame);
501     if (coreFrame->document()->isMediaDocument())
502         loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
503 
504     if (!m_manualLoader)
505         return;
506 
507     if (!m_hasSentResponseToPlugin) {
508         m_manualLoader->didReceiveResponse(loader->response());
509         // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
510         // setting up this stream can cause the main document load to be cancelled, setting m_manualLoader
511         // to null
512         if (!m_manualLoader)
513             return;
514         m_hasSentResponseToPlugin = true;
515     }
516     m_manualLoader->didReceiveData(data, length);
517 }
518 
finishedLoading(DocumentLoader * loader)519 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
520 {
521     // Telling the frame we received some data and passing 0 as the data is our
522     // way to get work done that is normally done when the first bit of data is
523     // received, even for the case of a document with no data (like about:blank)
524     committedLoad(loader, 0, 0);
525 
526     if (!m_manualLoader)
527         return;
528 
529     m_manualLoader->didFinishLoading();
530     m_manualLoader = 0;
531     m_hasSentResponseToPlugin = false;
532 }
533 
updateGlobalHistory()534 void WebFrameLoaderClient::updateGlobalHistory()
535 {
536     DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
537     WebView* webView = m_webFrame->webView();
538     COMPtr<IWebHistoryDelegate> historyDelegate;
539     webView->historyDelegate(&historyDelegate);
540 
541     if (historyDelegate) {
542         COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(loader->response()));
543         COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(loader->originalRequestCopy()));
544 
545         COMPtr<IWebNavigationData> navigationData(AdoptCOM, WebNavigationData::createInstance(
546             loader->urlForHistory(), loader->title().string(), urlRequest.get(), urlResponse.get(), loader->substituteData().isValid(), loader->clientRedirectSourceForHistory()));
547 
548         historyDelegate->didNavigateWithNavigationData(webView, navigationData.get(), m_webFrame);
549         return;
550     }
551 
552     WebHistory* history = WebHistory::sharedHistory();
553     if (!history)
554         return;
555 
556     history->visitedURL(loader->urlForHistory(), loader->title().string(), loader->originalRequestCopy().httpMethod(), loader->urlForHistoryReflectsFailure(), !loader->clientRedirectSourceForHistory());
557 }
558 
updateGlobalHistoryRedirectLinks()559 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
560 {
561     WebView* webView = m_webFrame->webView();
562     COMPtr<IWebHistoryDelegate> historyDelegate;
563     webView->historyDelegate(&historyDelegate);
564 
565     WebHistory* history = WebHistory::sharedHistory();
566 
567     DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
568     ASSERT(loader->unreachableURL().isEmpty());
569 
570     if (!loader->clientRedirectSourceForHistory().isNull()) {
571         if (historyDelegate) {
572             BString sourceURL(loader->clientRedirectSourceForHistory());
573             BString destURL(loader->clientRedirectDestinationForHistory());
574             historyDelegate->didPerformClientRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
575         } else {
576             if (history) {
577                 if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->clientRedirectSourceForHistory())) {
578                     COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
579                     webHistoryItem->historyItem()->addRedirectURL(loader->clientRedirectDestinationForHistory());
580                 }
581             }
582         }
583     }
584 
585     if (!loader->serverRedirectSourceForHistory().isNull()) {
586         if (historyDelegate) {
587             BString sourceURL(loader->serverRedirectSourceForHistory());
588             BString destURL(loader->serverRedirectDestinationForHistory());
589             historyDelegate->didPerformServerRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
590         } else {
591             if (history) {
592                 if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->serverRedirectSourceForHistory())) {
593                     COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
594                     webHistoryItem->historyItem()->addRedirectURL(loader->serverRedirectDestinationForHistory());
595                 }
596             }
597         }
598     }
599 }
600 
shouldGoToHistoryItem(HistoryItem *) const601 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const
602 {
603     return true;
604 }
605 
shouldStopLoadingForHistoryItem(HistoryItem *) const606 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem*) const
607 {
608     return true;
609 }
610 
dispatchDidAddBackForwardItem(HistoryItem *) const611 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
612 {
613 }
614 
dispatchDidRemoveBackForwardItem(HistoryItem *) const615 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const
616 {
617 }
618 
dispatchDidChangeBackForwardIndex() const619 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const
620 {
621 }
622 
updateGlobalHistoryItemForPage()623 void WebFrameLoaderClient::updateGlobalHistoryItemForPage()
624 {
625     HistoryItem* historyItem = 0;
626     WebView* webView = m_webFrame->webView();
627 
628     if (Page* page = webView->page()) {
629         if (!page->settings()->privateBrowsingEnabled())
630             historyItem = page->backForward()->currentItem();
631     }
632 
633     webView->setGlobalHistoryItem(historyItem);
634 }
635 
didDisplayInsecureContent()636 void WebFrameLoaderClient::didDisplayInsecureContent()
637 {
638     WebView* webView = m_webFrame->webView();
639     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
640     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
641         return;
642 
643     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
644     if (!frameLoadDelegatePriv2)
645         return;
646 
647     frameLoadDelegatePriv2->didDisplayInsecureContent(webView);
648 }
649 
didRunInsecureContent(SecurityOrigin * origin,const KURL & insecureURL)650 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin, const KURL& insecureURL)
651 {
652     COMPtr<IWebSecurityOrigin> webSecurityOrigin = WebSecurityOrigin::createInstance(origin);
653 
654     WebView* webView = m_webFrame->webView();
655     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
656     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
657         return;
658 
659     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
660     if (!frameLoadDelegatePriv2)
661         return;
662 
663     frameLoadDelegatePriv2->didRunInsecureContent(webView, webSecurityOrigin.get());
664 }
665 
createDocumentLoader(const ResourceRequest & request,const SubstituteData & substituteData)666 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
667 {
668     RefPtr<WebDocumentLoader> loader = WebDocumentLoader::create(request, substituteData);
669 
670     COMPtr<WebDataSource> dataSource(AdoptCOM, WebDataSource::createInstance(loader.get()));
671 
672     loader->setDataSource(dataSource.get());
673     return loader.release();
674 }
675 
setTitle(const StringWithDirection & title,const KURL & url)676 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url)
677 {
678     WebView* webView = m_webFrame->webView();
679     COMPtr<IWebHistoryDelegate> historyDelegate;
680     webView->historyDelegate(&historyDelegate);
681     if (historyDelegate) {
682         BString titleBSTR(title.string());
683         BString urlBSTR(url.string());
684         historyDelegate->updateHistoryTitle(webView, titleBSTR, urlBSTR);
685         return;
686     }
687 
688     BOOL privateBrowsingEnabled = FALSE;
689     COMPtr<IWebPreferences> preferences;
690     if (SUCCEEDED(m_webFrame->webView()->preferences(&preferences)))
691         preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
692     if (privateBrowsingEnabled)
693         return;
694 
695     // update title in global history
696     COMPtr<WebHistory> history = webHistory();
697     if (!history)
698         return;
699 
700     COMPtr<IWebHistoryItem> item;
701     if (FAILED(history->itemForURL(BString(url.string()), &item)))
702         return;
703 
704     COMPtr<IWebHistoryItemPrivate> itemPrivate(Query, item);
705     if (!itemPrivate)
706         return;
707 
708     itemPrivate->setTitle(BString(title.string()));
709 }
710 
savePlatformDataToCachedFrame(CachedFrame * cachedFrame)711 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
712 {
713 #if USE(CFNETWORK)
714     Frame* coreFrame = core(m_webFrame);
715     if (!coreFrame)
716         return;
717 
718     ASSERT(coreFrame->loader()->documentLoader() == cachedFrame->documentLoader());
719 
720     WebCachedFramePlatformData* webPlatformData = new WebCachedFramePlatformData(static_cast<IWebDataSource*>(getWebDataSource(coreFrame->loader()->documentLoader())));
721     cachedFrame->setCachedFramePlatformData(webPlatformData);
722 #else
723     notImplemented();
724 #endif
725 }
726 
transitionToCommittedFromCachedFrame(CachedFrame *)727 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
728 {
729 }
730 
transitionToCommittedForNewPage()731 void WebFrameLoaderClient::transitionToCommittedForNewPage()
732 {
733     WebView* view = m_webFrame->webView();
734 
735     RECT rect;
736     view->frameRect(&rect);
737     bool transparent = view->transparent();
738     Color backgroundColor = transparent ? Color::transparent : Color::white;
739     core(m_webFrame)->createView(IntRect(rect).size(), backgroundColor, transparent, IntSize(), false);
740 }
741 
didSaveToPageCache()742 void WebFrameLoaderClient::didSaveToPageCache()
743 {
744 }
745 
didRestoreFromPageCache()746 void WebFrameLoaderClient::didRestoreFromPageCache()
747 {
748 }
749 
dispatchDidBecomeFrameset(bool)750 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool)
751 {
752 }
753 
canCachePage() const754 bool WebFrameLoaderClient::canCachePage() const
755 {
756     return true;
757 }
758 
createFrame(const KURL & url,const String & name,HTMLFrameOwnerElement * ownerElement,const String & referrer,bool,int,int)759 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
760                             const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
761 {
762     RefPtr<Frame> result = createFrame(url, name, ownerElement, referrer);
763     if (!result)
764         return 0;
765     return result.release();
766 }
767 
didTransferChildFrameToNewDocument(Page *)768 void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*)
769 {
770     Frame* coreFrame = core(m_webFrame);
771     ASSERT(coreFrame);
772     WebView* webView = kit(coreFrame->page());
773     if (m_webFrame->webView() != webView)
774         m_webFrame->setWebView(webView);
775 }
776 
transferLoadingResourceFromPage(unsigned long identifier,DocumentLoader * loader,const ResourceRequest & request,Page * oldPage)777 void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request, Page* oldPage)
778 {
779     assignIdentifierToInitialRequest(identifier, loader, request);
780 
781     WebView* oldWebView = kit(oldPage);
782     if (!oldWebView)
783         return;
784 
785     COMPtr<IWebResourceLoadDelegate> oldResourceLoadDelegate;
786     if (FAILED(oldWebView->resourceLoadDelegate(&oldResourceLoadDelegate)))
787         return;
788 
789     COMPtr<IWebResourceLoadDelegatePrivate2> oldResourceLoadDelegatePrivate2(Query, oldResourceLoadDelegate);
790     if (!oldResourceLoadDelegatePrivate2)
791         return;
792     oldResourceLoadDelegatePrivate2->removeIdentifierForRequest(oldWebView, identifier);
793 }
794 
createFrame(const KURL & URL,const String & name,HTMLFrameOwnerElement * ownerElement,const String & referrer)795 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
796 {
797     Frame* coreFrame = core(m_webFrame);
798     ASSERT(coreFrame);
799 
800     COMPtr<WebFrame> webFrame(AdoptCOM, WebFrame::createInstance());
801 
802     RefPtr<Frame> childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement);
803 
804     childFrame->tree()->setName(name);
805     coreFrame->tree()->appendChild(childFrame);
806     childFrame->init();
807 
808     coreFrame->loader()->loadURLIntoChildFrame(URL, referrer, childFrame.get());
809 
810     // The frame's onload handler may have removed it from the document.
811     if (!childFrame->tree()->parent())
812         return 0;
813 
814     return childFrame.release();
815 }
816 
dispatchDidFailToStartPlugin(const PluginView * pluginView) const817 void WebFrameLoaderClient::dispatchDidFailToStartPlugin(const PluginView* pluginView) const
818 {
819     WebView* webView = m_webFrame->webView();
820 
821     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
822     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
823         return;
824 
825     RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
826 
827     Frame* frame = core(m_webFrame);
828     ASSERT(frame == pluginView->parentFrame());
829 
830     if (!pluginView->pluginsPage().isNull()) {
831         KURL pluginPageURL = frame->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(pluginView->pluginsPage()));
832         if (pluginPageURL.protocolInHTTPFamily()) {
833             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
834             RetainPtr<CFStringRef> str(AdoptCF, pluginPageURL.string().createCFString());
835             CFDictionarySetValue(userInfo.get(), key, str.get());
836         }
837     }
838 
839     if (!pluginView->mimeType().isNull()) {
840         static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
841 
842         RetainPtr<CFStringRef> str(AdoptCF, pluginView->mimeType().createCFString());
843         CFDictionarySetValue(userInfo.get(), key, str.get());
844     }
845 
846     if (pluginView->plugin()) {
847         String pluginName = pluginView->plugin()->name();
848         if (!pluginName.isNull()) {
849             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
850             RetainPtr<CFStringRef> str(AdoptCF, pluginName.createCFString());
851             CFDictionarySetValue(userInfo.get(), key, str.get());
852         }
853     }
854 
855     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
856     userInfoBag->setDictionary(userInfo.get());
857 
858     int errorCode = 0;
859     switch (pluginView->status()) {
860         case PluginStatusCanNotFindPlugin:
861             errorCode = WebKitErrorCannotFindPlugIn;
862             break;
863         case PluginStatusCanNotLoadPlugin:
864             errorCode = WebKitErrorCannotLoadPlugIn;
865             break;
866         default:
867             ASSERT_NOT_REACHED();
868     }
869 
870     ResourceError resourceError(String(WebKitErrorDomain), errorCode, pluginView->url().string(), String());
871     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
872 
873     resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader()->documentLoader()));
874 }
875 
createPlugin(const IntSize & pluginSize,HTMLPlugInElement * element,const KURL & url,const Vector<String> & paramNames,const Vector<String> & paramValues,const String & mimeType,bool loadManually)876 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)
877 {
878     WebView* webView = m_webFrame->webView();
879 
880     COMPtr<IWebUIDelegate> ui;
881     if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) {
882         COMPtr<IWebUIDelegatePrivate> uiPrivate(Query, ui);
883 
884         if (uiPrivate) {
885             // Assemble the view arguments in a property bag.
886             HashMap<String, String> viewArguments;
887             for (unsigned i = 0; i < paramNames.size(); i++)
888                 viewArguments.set(paramNames[i], paramValues[i]);
889             COMPtr<IPropertyBag> viewArgumentsBag(AdoptCOM, COMPropertyBag<String>::adopt(viewArguments));
890             COMPtr<IDOMElement> containingElement(AdoptCOM, DOMElement::createInstance(element));
891 
892             HashMap<String, COMVariant> arguments;
893 
894             arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag);
895             arguments.set(WebEmbeddedViewBaseURLKey, url.string());
896             arguments.set(WebEmbeddedViewContainingElementKey, containingElement);
897             arguments.set(WebEmbeddedViewMIMETypeKey, mimeType);
898 
899             COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMVariant>::adopt(arguments));
900 
901             COMPtr<IWebEmbeddedView> view;
902             HRESULT result = uiPrivate->embeddedViewWithArguments(webView, m_webFrame, argumentsBag.get(), &view);
903             if (SUCCEEDED(result)) {
904                 HWND parentWindow;
905                 HRESULT hr = webView->viewWindow((OLE_HANDLE*)&parentWindow);
906                 ASSERT(SUCCEEDED(hr));
907 
908                 return EmbeddedWidget::create(view.get(), element, parentWindow, pluginSize);
909             }
910         }
911     }
912 
913     Frame* frame = core(m_webFrame);
914     RefPtr<PluginView> pluginView = PluginView::create(frame, pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
915 
916     if (pluginView->status() == PluginStatusLoadedSuccessfully)
917         return pluginView;
918 
919     dispatchDidFailToStartPlugin(pluginView.get());
920 
921     return 0;
922 }
923 
redirectDataToPlugin(Widget * pluginWidget)924 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
925 {
926     // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
927 
928     if (pluginWidget->isPluginView())
929         m_manualLoader = static_cast<PluginView*>(pluginWidget);
930     else
931         m_manualLoader = static_cast<EmbeddedWidget*>(pluginWidget);
932 }
933 
webHistory() const934 WebHistory* WebFrameLoaderClient::webHistory() const
935 {
936     if (m_webFrame != m_webFrame->webView()->topLevelFrame())
937         return 0;
938 
939     return WebHistory::sharedHistory();
940 }
941 
shouldUsePluginDocument(const String & mimeType) const942 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& mimeType) const
943 {
944     WebView* webView = m_webFrame->webView();
945     if (!webView)
946         return false;
947 
948     return webView->shouldUseEmbeddedView(mimeType);
949 }
950