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