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