• 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 #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/HTMLPlugInElement.h>
63 #include <WebCore/HistoryItem.h>
64 #include <WebCore/Page.h>
65 #include <WebCore/PluginPackage.h>
66 #include <WebCore/PluginView.h>
67 #include <WebCore/RenderPart.h>
68 #include <WebCore/ResourceHandle.h>
69 #include <WebCore/ScriptString.h>
70 #pragma warning(pop)
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 
dispatchDidLoadResourceByXMLHttpRequest(unsigned long,const ScriptString &)246 void WebFrameLoaderClient::dispatchDidLoadResourceByXMLHttpRequest(unsigned long, const ScriptString&)
247 {
248 }
249 
shouldCacheResponse(DocumentLoader * loader,unsigned long identifier,const ResourceResponse & response,const unsigned char * data,const unsigned long long length)250 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, const unsigned char* data, const unsigned long long length)
251 {
252     WebView* webView = m_webFrame->webView();
253     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
254     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
255         return true;
256 
257     COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate(Query, resourceLoadDelegate);
258     if (!resourceLoadDelegatePrivate)
259         return true;
260 
261     COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(response));
262     BOOL shouldCache;
263     if (SUCCEEDED(resourceLoadDelegatePrivate->shouldCacheResponse(webView, identifier, urlResponse.get(), data, length, getWebDataSource(loader), &shouldCache)))
264         return shouldCache;
265 
266     return true;
267 }
268 
dispatchDidHandleOnloadEvents()269 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
270 {
271     WebView* webView = m_webFrame->webView();
272     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
273     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
274         frameLoadDelegatePriv->didHandleOnloadEventsForFrame(webView, m_webFrame);
275 }
276 
dispatchDidReceiveServerRedirectForProvisionalLoad()277 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
278 {
279     WebView* webView = m_webFrame->webView();
280     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
281     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
282         frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(webView, m_webFrame);
283 }
284 
dispatchDidCancelClientRedirect()285 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
286 {
287     WebView* webView = m_webFrame->webView();
288     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
289     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
290         frameLoadDelegate->didCancelClientRedirectForFrame(webView, m_webFrame);
291 }
292 
dispatchWillPerformClientRedirect(const KURL & url,double delay,double fireDate)293 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
294 {
295     WebView* webView = m_webFrame->webView();
296     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
297     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
298         frameLoadDelegate->willPerformClientRedirectToURL(webView, BString(url.string()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), m_webFrame);
299 }
300 
dispatchDidChangeLocationWithinPage()301 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
302 {
303     WebView* webView = m_webFrame->webView();
304     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
305     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
306         frameLoadDelegate->didChangeLocationWithinPageForFrame(webView, m_webFrame);
307 }
308 
dispatchDidPushStateWithinPage()309 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
310 {
311     WebView* webView = m_webFrame->webView();
312     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
313     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
314         return;
315 
316     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
317     if (!frameLoadDelegatePriv2)
318         return;
319 
320     frameLoadDelegatePriv2->didPushStateWithinPageForFrame(webView, m_webFrame);
321 }
322 
dispatchDidReplaceStateWithinPage()323 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
324 {
325     WebView* webView = m_webFrame->webView();
326     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
327     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
328         return;
329 
330     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
331     if (!frameLoadDelegatePriv2)
332         return;
333 
334     frameLoadDelegatePriv2->didReplaceStateWithinPageForFrame(webView, m_webFrame);
335 }
336 
dispatchDidPopStateWithinPage()337 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
338 {
339     WebView* webView = m_webFrame->webView();
340     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
341     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
342         return;
343 
344     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
345     if (!frameLoadDelegatePriv2)
346         return;
347 
348     frameLoadDelegatePriv2->didPopStateWithinPageForFrame(webView, m_webFrame);
349 }
dispatchWillClose()350 void WebFrameLoaderClient::dispatchWillClose()
351 {
352     WebView* webView = m_webFrame->webView();
353     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
354     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
355         frameLoadDelegate->willCloseFrame(webView, m_webFrame);
356 }
357 
dispatchDidReceiveIcon()358 void WebFrameLoaderClient::dispatchDidReceiveIcon()
359 {
360     m_webFrame->webView()->dispatchDidReceiveIconFromWebFrame(m_webFrame);
361 }
362 
dispatchDidStartProvisionalLoad()363 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
364 {
365     WebView* webView = m_webFrame->webView();
366     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
367     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
368         frameLoadDelegate->didStartProvisionalLoadForFrame(webView, m_webFrame);
369 }
370 
dispatchDidReceiveTitle(const String & title)371 void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title)
372 {
373     WebView* webView = m_webFrame->webView();
374     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
375     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
376         frameLoadDelegate->didReceiveTitle(webView, BString(title), m_webFrame);
377 }
378 
dispatchDidCommitLoad()379 void WebFrameLoaderClient::dispatchDidCommitLoad()
380 {
381     WebView* webView = m_webFrame->webView();
382     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
383     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
384         frameLoadDelegate->didCommitLoadForFrame(webView, m_webFrame);
385 }
386 
dispatchDidFinishDocumentLoad()387 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
388 {
389     WebView* webView = m_webFrame->webView();
390     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
391     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
392         frameLoadDelegatePriv->didFinishDocumentLoadForFrame(webView, m_webFrame);
393 }
394 
dispatchDidFinishLoad()395 void WebFrameLoaderClient::dispatchDidFinishLoad()
396 {
397     WebView* webView = m_webFrame->webView();
398     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
399     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
400         frameLoadDelegate->didFinishLoadForFrame(webView, m_webFrame);
401 }
402 
dispatchDidFirstLayout()403 void WebFrameLoaderClient::dispatchDidFirstLayout()
404 {
405     WebView* webView = m_webFrame->webView();
406     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
407     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
408         frameLoadDelegatePriv->didFirstLayoutInFrame(webView, m_webFrame);
409 }
410 
dispatchDidFirstVisuallyNonEmptyLayout()411 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
412 {
413     WebView* webView = m_webFrame->webView();
414     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePrivate;
415     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate)
416         frameLoadDelegatePrivate->didFirstVisuallyNonEmptyLayoutInFrame(webView, m_webFrame);
417 }
418 
dispatchCreatePage()419 Frame* WebFrameLoaderClient::dispatchCreatePage()
420 {
421     WebView* webView = m_webFrame->webView();
422 
423     COMPtr<IWebUIDelegate> ui;
424     if (FAILED(webView->uiDelegate(&ui)))
425         return 0;
426 
427     COMPtr<IWebView> newWebView;
428     if (FAILED(ui->createWebViewWithRequest(webView, 0, &newWebView)))
429         return 0;
430 
431     COMPtr<IWebFrame> mainFrame;
432     if (FAILED(newWebView->mainFrame(&mainFrame)))
433         return 0;
434 
435     COMPtr<WebFrame> mainFrameImpl(Query, mainFrame);
436     return core(mainFrameImpl.get());
437 }
438 
dispatchShow()439 void WebFrameLoaderClient::dispatchShow()
440 {
441     WebView* webView = m_webFrame->webView();
442     COMPtr<IWebUIDelegate> ui;
443     if (SUCCEEDED(webView->uiDelegate(&ui)))
444         ui->webViewShow(webView);
445 }
446 
dispatchDidLoadMainResource(DocumentLoader *)447 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
448 {
449 }
450 
setMainDocumentError(DocumentLoader *,const ResourceError & error)451 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
452 {
453     if (!m_manualLoader)
454         return;
455 
456     m_manualLoader->didFail(error);
457     m_manualLoader = 0;
458     m_hasSentResponseToPlugin = false;
459 }
460 
postProgressStartedNotification()461 void WebFrameLoaderClient::postProgressStartedNotification()
462 {
463     static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
464     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
465     notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
466 }
467 
postProgressEstimateChangedNotification()468 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
469 {
470     static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
471     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
472     notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
473 }
474 
postProgressFinishedNotification()475 void WebFrameLoaderClient::postProgressFinishedNotification()
476 {
477     static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
478     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
479     notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
480 }
481 
committedLoad(DocumentLoader * loader,const char * data,int length)482 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
483 {
484     // FIXME: This should probably go through the data source.
485     const String& textEncoding = loader->response().textEncodingName();
486 
487     if (!m_manualLoader)
488         receivedData(data, length, textEncoding);
489 
490     if (!m_manualLoader)
491         return;
492 
493     if (!m_hasSentResponseToPlugin) {
494         m_manualLoader->didReceiveResponse(core(m_webFrame)->loader()->documentLoader()->response());
495         // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
496         // setting up this stream can cause the main document load to be cancelled, setting m_manualLoader
497         // to null
498         if (!m_manualLoader)
499             return;
500         m_hasSentResponseToPlugin = true;
501     }
502     m_manualLoader->didReceiveData(data, length);
503 }
504 
receivedData(const char * data,int length,const String & textEncoding)505 void WebFrameLoaderClient::receivedData(const char* data, int length, const String& textEncoding)
506 {
507     Frame* coreFrame = core(m_webFrame);
508     if (!coreFrame)
509         return;
510 
511     // Set the encoding. This only needs to be done once, but it's harmless to do it again later.
512     String encoding = coreFrame->loader()->documentLoader()->overrideEncoding();
513     bool userChosen = !encoding.isNull();
514     if (encoding.isNull())
515         encoding = textEncoding;
516     coreFrame->loader()->setEncoding(encoding, userChosen);
517 
518     coreFrame->loader()->addData(data, length);
519 }
520 
finishedLoading(DocumentLoader * loader)521 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
522 {
523     // Telling the frame we received some data and passing 0 as the data is our
524     // way to get work done that is normally done when the first bit of data is
525     // received, even for the case of a document with no data (like about:blank)
526     if (!m_manualLoader) {
527         committedLoad(loader, 0, 0);
528         return;
529     }
530 
531     m_manualLoader->didFinishLoading();
532     m_manualLoader = 0;
533     m_hasSentResponseToPlugin = false;
534 }
535 
updateGlobalHistory()536 void WebFrameLoaderClient::updateGlobalHistory()
537 {
538     DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
539     WebView* webView = m_webFrame->webView();
540     COMPtr<IWebHistoryDelegate> historyDelegate;
541     webView->historyDelegate(&historyDelegate);
542 
543     if (historyDelegate) {
544         COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(loader->response()));
545         COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(loader->originalRequestCopy()));
546 
547         COMPtr<IWebNavigationData> navigationData(AdoptCOM, WebNavigationData::createInstance(
548             loader->urlForHistory(), loader->title(), urlRequest.get(), urlResponse.get(), loader->substituteData().isValid(), loader->clientRedirectSourceForHistory()));
549 
550         historyDelegate->didNavigateWithNavigationData(webView, navigationData.get(), m_webFrame);
551         return;
552     }
553 
554     WebHistory* history = WebHistory::sharedHistory();
555     if (!history)
556         return;
557 
558     history->visitedURL(loader->urlForHistory(), loader->title(), loader->originalRequestCopy().httpMethod(), loader->urlForHistoryReflectsFailure(), !loader->clientRedirectSourceForHistory());
559 }
560 
updateGlobalHistoryRedirectLinks()561 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
562 {
563     WebView* webView = m_webFrame->webView();
564     COMPtr<IWebHistoryDelegate> historyDelegate;
565     webView->historyDelegate(&historyDelegate);
566 
567     WebHistory* history = WebHistory::sharedHistory();
568 
569     DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
570     ASSERT(loader->unreachableURL().isEmpty());
571 
572     if (!loader->clientRedirectSourceForHistory().isNull()) {
573         if (historyDelegate) {
574             BString sourceURL(loader->clientRedirectSourceForHistory());
575             BString destURL(loader->clientRedirectDestinationForHistory());
576             historyDelegate->didPerformClientRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
577         } else {
578             if (history) {
579                 if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->clientRedirectSourceForHistory())) {
580                     COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
581                     webHistoryItem->historyItem()->addRedirectURL(loader->clientRedirectDestinationForHistory());
582                 }
583             }
584         }
585     }
586 
587     if (!loader->serverRedirectSourceForHistory().isNull()) {
588         if (historyDelegate) {
589             BString sourceURL(loader->serverRedirectSourceForHistory());
590             BString destURL(loader->serverRedirectDestinationForHistory());
591             historyDelegate->didPerformServerRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
592         } else {
593             if (history) {
594                 if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->serverRedirectSourceForHistory())) {
595                     COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
596                     webHistoryItem->historyItem()->addRedirectURL(loader->serverRedirectDestinationForHistory());
597                 }
598             }
599         }
600     }
601 }
602 
shouldGoToHistoryItem(HistoryItem *) const603 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const
604 {
605     return true;
606 }
607 
dispatchDidAddBackForwardItem(HistoryItem *) const608 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
609 {
610 }
611 
dispatchDidRemoveBackForwardItem(HistoryItem *) const612 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const
613 {
614 }
615 
dispatchDidChangeBackForwardIndex() const616 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const
617 {
618 }
619 
didDisplayInsecureContent()620 void WebFrameLoaderClient::didDisplayInsecureContent()
621 {
622     WebView* webView = m_webFrame->webView();
623     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
624     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
625         return;
626 
627     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
628     if (!frameLoadDelegatePriv2)
629         return;
630 
631     frameLoadDelegatePriv2->didDisplayInsecureContent(webView);
632 }
633 
didRunInsecureContent(SecurityOrigin * origin)634 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin)
635 {
636     COMPtr<IWebSecurityOrigin> webSecurityOrigin = WebSecurityOrigin::createInstance(origin);
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->didRunInsecureContent(webView, webSecurityOrigin.get());
648 }
649 
createDocumentLoader(const ResourceRequest & request,const SubstituteData & substituteData)650 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
651 {
652     RefPtr<WebDocumentLoader> loader = WebDocumentLoader::create(request, substituteData);
653 
654     COMPtr<WebDataSource> dataSource(AdoptCOM, WebDataSource::createInstance(loader.get()));
655 
656     loader->setDataSource(dataSource.get());
657     return loader.release();
658 }
659 
setTitle(const String & title,const KURL & url)660 void WebFrameLoaderClient::setTitle(const String& title, const KURL& url)
661 {
662     WebView* webView = m_webFrame->webView();
663     COMPtr<IWebHistoryDelegate> historyDelegate;
664     webView->historyDelegate(&historyDelegate);
665     if (historyDelegate) {
666         BString titleBSTR(title);
667         BString urlBSTR(url.string());
668         historyDelegate->updateHistoryTitle(webView, titleBSTR, urlBSTR);
669         return;
670     }
671 
672     BOOL privateBrowsingEnabled = FALSE;
673     COMPtr<IWebPreferences> preferences;
674     if (SUCCEEDED(m_webFrame->webView()->preferences(&preferences)))
675         preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
676     if (privateBrowsingEnabled)
677         return;
678 
679     // update title in global history
680     COMPtr<WebHistory> history = webHistory();
681     if (!history)
682         return;
683 
684     COMPtr<IWebHistoryItem> item;
685     if (FAILED(history->itemForURL(BString(url.string()), &item)))
686         return;
687 
688     COMPtr<IWebHistoryItemPrivate> itemPrivate(Query, item);
689     if (!itemPrivate)
690         return;
691 
692     itemPrivate->setTitle(BString(title));
693 }
694 
savePlatformDataToCachedFrame(CachedFrame * cachedFrame)695 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
696 {
697 #if USE(CFNETWORK)
698     Frame* coreFrame = core(m_webFrame);
699     if (!coreFrame)
700         return;
701 
702     ASSERT(coreFrame->loader()->documentLoader() == cachedFrame->documentLoader());
703 
704     WebCachedFramePlatformData* webPlatformData = new WebCachedFramePlatformData(static_cast<IWebDataSource*>(getWebDataSource(coreFrame->loader()->documentLoader())));
705     cachedFrame->setCachedFramePlatformData(webPlatformData);
706 #else
707     notImplemented();
708 #endif
709 }
710 
transitionToCommittedFromCachedFrame(CachedFrame *)711 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
712 {
713 }
714 
transitionToCommittedForNewPage()715 void WebFrameLoaderClient::transitionToCommittedForNewPage()
716 {
717     WebView* view = m_webFrame->webView();
718 
719     RECT rect;
720     view->frameRect(&rect);
721     bool transparent = view->transparent();
722     Color backgroundColor = transparent ? Color::transparent : Color::white;
723     core(m_webFrame)->createView(IntRect(rect).size(), backgroundColor, transparent, IntSize(), false);
724 }
725 
canCachePage() const726 bool WebFrameLoaderClient::canCachePage() const
727 {
728     return true;
729 }
730 
createFrame(const KURL & url,const String & name,HTMLFrameOwnerElement * ownerElement,const String & referrer,bool,int,int)731 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
732                             const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
733 {
734     RefPtr<Frame> result = createFrame(url, name, ownerElement, referrer);
735     if (!result)
736         return 0;
737     return result.release();
738 }
739 
createFrame(const KURL & URL,const String & name,HTMLFrameOwnerElement * ownerElement,const String & referrer)740 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
741 {
742     Frame* coreFrame = core(m_webFrame);
743     ASSERT(coreFrame);
744 
745     COMPtr<WebFrame> webFrame(AdoptCOM, WebFrame::createInstance());
746 
747     RefPtr<Frame> childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement);
748 
749     coreFrame->tree()->appendChild(childFrame);
750     childFrame->tree()->setName(name);
751     childFrame->init();
752 
753     coreFrame->loader()->loadURLIntoChildFrame(URL, referrer, childFrame.get());
754 
755     // The frame's onload handler may have removed it from the document.
756     if (!childFrame->tree()->parent())
757         return 0;
758 
759     return childFrame.release();
760 }
761 
dispatchDidFailToStartPlugin(const PluginView * pluginView) const762 void WebFrameLoaderClient::dispatchDidFailToStartPlugin(const PluginView* pluginView) const
763 {
764     WebView* webView = m_webFrame->webView();
765 
766     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
767     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
768         return;
769 
770     RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
771 
772     Frame* frame = core(m_webFrame);
773     ASSERT(frame == pluginView->parentFrame());
774 
775     if (!pluginView->pluginsPage().isNull()) {
776         KURL pluginPageURL = frame->document()->completeURL(deprecatedParseURL(pluginView->pluginsPage()));
777         if (pluginPageURL.protocolInHTTPFamily()) {
778             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
779             RetainPtr<CFStringRef> str(AdoptCF, pluginPageURL.string().createCFString());
780             CFDictionarySetValue(userInfo.get(), key, str.get());
781         }
782     }
783 
784     if (!pluginView->mimeType().isNull()) {
785         static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
786 
787         RetainPtr<CFStringRef> str(AdoptCF, pluginView->mimeType().createCFString());
788         CFDictionarySetValue(userInfo.get(), key, str.get());
789     }
790 
791     if (pluginView->plugin()) {
792         String pluginName = pluginView->plugin()->name();
793         if (!pluginName.isNull()) {
794             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
795             RetainPtr<CFStringRef> str(AdoptCF, pluginName.createCFString());
796             CFDictionarySetValue(userInfo.get(), key, str.get());
797         }
798     }
799 
800     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
801     userInfoBag->setDictionary(userInfo.get());
802 
803     int errorCode = 0;
804     switch (pluginView->status()) {
805         case PluginStatusCanNotFindPlugin:
806             errorCode = WebKitErrorCannotFindPlugIn;
807             break;
808         case PluginStatusCanNotLoadPlugin:
809             errorCode = WebKitErrorCannotLoadPlugIn;
810             break;
811         default:
812             ASSERT_NOT_REACHED();
813     }
814 
815     ResourceError resourceError(String(WebKitErrorDomain), errorCode, pluginView->url().string(), String());
816     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
817 
818     resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader()->documentLoader()));
819 }
820 
createPlugin(const IntSize & pluginSize,HTMLPlugInElement * element,const KURL & url,const Vector<String> & paramNames,const Vector<String> & paramValues,const String & mimeType,bool loadManually)821 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)
822 {
823     WebView* webView = m_webFrame->webView();
824 
825     COMPtr<IWebUIDelegate> ui;
826     if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) {
827         COMPtr<IWebUIDelegatePrivate> uiPrivate(Query, ui);
828 
829         if (uiPrivate) {
830             // Assemble the view arguments in a property bag.
831             HashMap<String, String> viewArguments;
832             for (unsigned i = 0; i < paramNames.size(); i++)
833                 viewArguments.set(paramNames[i], paramValues[i]);
834             COMPtr<IPropertyBag> viewArgumentsBag(AdoptCOM, COMPropertyBag<String>::adopt(viewArguments));
835             COMPtr<IDOMElement> containingElement(AdoptCOM, DOMElement::createInstance(element));
836 
837             HashMap<String, COMVariant> arguments;
838 
839             arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag);
840             arguments.set(WebEmbeddedViewBaseURLKey, url.string());
841             arguments.set(WebEmbeddedViewContainingElementKey, containingElement);
842             arguments.set(WebEmbeddedViewMIMETypeKey, mimeType);
843 
844             COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMVariant>::adopt(arguments));
845 
846             COMPtr<IWebEmbeddedView> view;
847             HRESULT result = uiPrivate->embeddedViewWithArguments(webView, m_webFrame, argumentsBag.get(), &view);
848             if (SUCCEEDED(result)) {
849                 HWND parentWindow;
850                 HRESULT hr = webView->viewWindow((OLE_HANDLE*)&parentWindow);
851                 ASSERT(SUCCEEDED(hr));
852 
853                 return EmbeddedWidget::create(view.get(), element, parentWindow, pluginSize);
854             }
855         }
856     }
857 
858     Frame* frame = core(m_webFrame);
859     RefPtr<PluginView> pluginView = PluginView::create(frame, pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
860 
861     if (pluginView->status() == PluginStatusLoadedSuccessfully)
862         return pluginView;
863 
864     dispatchDidFailToStartPlugin(pluginView.get());
865 
866     return pluginView;
867 }
868 
redirectDataToPlugin(Widget * pluginWidget)869 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
870 {
871     // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
872 
873     if (pluginWidget->isPluginView())
874         m_manualLoader = static_cast<PluginView*>(pluginWidget);
875     else
876         m_manualLoader = static_cast<EmbeddedWidget*>(pluginWidget);
877 }
878 
webHistory() const879 WebHistory* WebFrameLoaderClient::webHistory() const
880 {
881     if (m_webFrame != m_webFrame->webView()->topLevelFrame())
882         return 0;
883 
884     return WebHistory::sharedHistory();
885 }
886 
shouldUsePluginDocument(const String & mimeType) const887 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& mimeType) const
888 {
889     WebView* webView = m_webFrame->webView();
890     if (!webView)
891         return false;
892 
893     return webView->shouldUseEmbeddedView(mimeType);
894 }
895