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 75 static WebDataSource* getWebDataSource(DocumentLoader* loader) 76 { 77 return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0; 78 } 79 80 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* webFrame) 81 : m_webFrame(webFrame) 82 , m_manualLoader(0) 83 , m_hasSentResponseToPlugin(false) 84 { 85 ASSERT_ARG(webFrame, webFrame); 86 } 87 88 WebFrameLoaderClient::~WebFrameLoaderClient() 89 { 90 } 91 92 bool WebFrameLoaderClient::hasWebView() const 93 { 94 return m_webFrame->webView(); 95 } 96 97 void WebFrameLoaderClient::forceLayout() 98 { 99 Frame* frame = core(m_webFrame); 100 if (!frame) 101 return; 102 103 if (frame->document() && frame->document()->inPageCache()) 104 return; 105 106 FrameView* view = frame->view(); 107 if (!view) 108 return; 109 110 view->setNeedsLayout(); 111 view->forceLayout(true); 112 } 113 114 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) 115 { 116 WebView* webView = m_webFrame->webView(); 117 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; 118 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) 119 return; 120 121 COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request)); 122 resourceLoadDelegate->identifierForInitialRequest(webView, webURLRequest.get(), getWebDataSource(loader), identifier); 123 } 124 125 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader* loader, unsigned long identifier) 126 { 127 WebView* webView = m_webFrame->webView(); 128 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; 129 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) 130 return true; 131 132 COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate; 133 if (FAILED(resourceLoadDelegate->QueryInterface(IID_IWebResourceLoadDelegatePrivate, reinterpret_cast<void**>(&resourceLoadDelegatePrivate)))) 134 return true; 135 136 BOOL shouldUse; 137 if (SUCCEEDED(resourceLoadDelegatePrivate->shouldUseCredentialStorage(webView, identifier, getWebDataSource(loader), &shouldUse))) 138 return shouldUse; 139 140 return true; 141 } 142 143 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge) 144 { 145 #if USE(CFNETWORK) 146 ASSERT(challenge.authenticationClient()); 147 148 WebView* webView = m_webFrame->webView(); 149 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; 150 if (SUCCEEDED(webView->resourceLoadDelegate(&resourceLoadDelegate))) { 151 COMPtr<WebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge)); 152 if (SUCCEEDED(resourceLoadDelegate->didReceiveAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader)))) 153 return; 154 } 155 156 // If the ResourceLoadDelegate doesn't exist or fails to handle the call, we tell the ResourceHandle 157 // to continue without credential - this is the best approximation of Mac behavior 158 challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge); 159 #else 160 notImplemented(); 161 #endif 162 } 163 164 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge) 165 { 166 WebView* webView = m_webFrame->webView(); 167 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; 168 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) 169 return; 170 171 COMPtr<WebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge)); 172 resourceLoadDelegate->didCancelAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader)); 173 } 174 175 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) 176 { 177 WebView* webView = m_webFrame->webView(); 178 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; 179 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) 180 return; 181 182 COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request)); 183 COMPtr<WebURLResponse> webURLRedirectResponse(AdoptCOM, WebURLResponse::createInstance(redirectResponse)); 184 185 COMPtr<IWebURLRequest> newWebURLRequest; 186 if (FAILED(resourceLoadDelegate->willSendRequest(webView, identifier, webURLRequest.get(), webURLRedirectResponse.get(), getWebDataSource(loader), &newWebURLRequest))) 187 return; 188 189 if (webURLRequest == newWebURLRequest) 190 return; 191 192 if (!newWebURLRequest) { 193 request = ResourceRequest(); 194 return; 195 } 196 197 COMPtr<WebMutableURLRequest> newWebURLRequestImpl(Query, newWebURLRequest); 198 if (!newWebURLRequestImpl) 199 return; 200 201 request = newWebURLRequestImpl->resourceRequest(); 202 } 203 204 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response) 205 { 206 WebView* webView = m_webFrame->webView(); 207 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; 208 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) 209 return; 210 211 COMPtr<WebURLResponse> webURLResponse(AdoptCOM, WebURLResponse::createInstance(response)); 212 resourceLoadDelegate->didReceiveResponse(webView, identifier, webURLResponse.get(), getWebDataSource(loader)); 213 } 214 215 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length) 216 { 217 WebView* webView = m_webFrame->webView(); 218 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; 219 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) 220 return; 221 222 resourceLoadDelegate->didReceiveContentLength(webView, identifier, length, getWebDataSource(loader)); 223 } 224 225 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier) 226 { 227 WebView* webView = m_webFrame->webView(); 228 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; 229 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) 230 return; 231 232 resourceLoadDelegate->didFinishLoadingFromDataSource(webView, identifier, getWebDataSource(loader)); 233 } 234 235 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error) 236 { 237 WebView* webView = m_webFrame->webView(); 238 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; 239 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) 240 return; 241 242 COMPtr<WebError> webError(AdoptCOM, WebError::createInstance(error)); 243 resourceLoadDelegate->didFailLoadingWithError(webView, identifier, webError.get(), getWebDataSource(loader)); 244 } 245 246 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, const unsigned char* data, const unsigned long long length) 247 { 248 WebView* webView = m_webFrame->webView(); 249 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; 250 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) 251 return true; 252 253 COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate(Query, resourceLoadDelegate); 254 if (!resourceLoadDelegatePrivate) 255 return true; 256 257 COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(response)); 258 BOOL shouldCache; 259 if (SUCCEEDED(resourceLoadDelegatePrivate->shouldCacheResponse(webView, identifier, urlResponse.get(), data, length, getWebDataSource(loader), &shouldCache))) 260 return shouldCache; 261 262 return true; 263 } 264 265 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents() 266 { 267 WebView* webView = m_webFrame->webView(); 268 COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv; 269 if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv) 270 frameLoadDelegatePriv->didHandleOnloadEventsForFrame(webView, m_webFrame); 271 } 272 273 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad() 274 { 275 WebView* webView = m_webFrame->webView(); 276 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate; 277 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) 278 frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(webView, m_webFrame); 279 } 280 281 void WebFrameLoaderClient::dispatchDidCancelClientRedirect() 282 { 283 WebView* webView = m_webFrame->webView(); 284 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate; 285 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) 286 frameLoadDelegate->didCancelClientRedirectForFrame(webView, m_webFrame); 287 } 288 289 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate) 290 { 291 WebView* webView = m_webFrame->webView(); 292 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate; 293 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) 294 frameLoadDelegate->willPerformClientRedirectToURL(webView, BString(url.string()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), m_webFrame); 295 } 296 297 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage() 298 { 299 WebView* webView = m_webFrame->webView(); 300 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate; 301 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) 302 frameLoadDelegate->didChangeLocationWithinPageForFrame(webView, m_webFrame); 303 } 304 305 void WebFrameLoaderClient::dispatchDidPushStateWithinPage() 306 { 307 WebView* webView = m_webFrame->webView(); 308 COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv; 309 if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) 310 return; 311 312 COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); 313 if (!frameLoadDelegatePriv2) 314 return; 315 316 frameLoadDelegatePriv2->didPushStateWithinPageForFrame(webView, m_webFrame); 317 } 318 319 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage() 320 { 321 WebView* webView = m_webFrame->webView(); 322 COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv; 323 if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) 324 return; 325 326 COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); 327 if (!frameLoadDelegatePriv2) 328 return; 329 330 frameLoadDelegatePriv2->didReplaceStateWithinPageForFrame(webView, m_webFrame); 331 } 332 333 void WebFrameLoaderClient::dispatchDidPopStateWithinPage() 334 { 335 WebView* webView = m_webFrame->webView(); 336 COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv; 337 if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) 338 return; 339 340 COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); 341 if (!frameLoadDelegatePriv2) 342 return; 343 344 frameLoadDelegatePriv2->didPopStateWithinPageForFrame(webView, m_webFrame); 345 } 346 void WebFrameLoaderClient::dispatchWillClose() 347 { 348 WebView* webView = m_webFrame->webView(); 349 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate; 350 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) 351 frameLoadDelegate->willCloseFrame(webView, m_webFrame); 352 } 353 354 void WebFrameLoaderClient::dispatchDidReceiveIcon() 355 { 356 m_webFrame->webView()->dispatchDidReceiveIconFromWebFrame(m_webFrame); 357 } 358 359 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad() 360 { 361 WebView* webView = m_webFrame->webView(); 362 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate; 363 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) 364 frameLoadDelegate->didStartProvisionalLoadForFrame(webView, m_webFrame); 365 } 366 367 void WebFrameLoaderClient::dispatchDidReceiveTitle(const 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 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 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 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 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 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 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 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 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 458 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*) 459 { 460 } 461 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 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 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 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 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 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 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 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 601 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const 602 { 603 return true; 604 } 605 606 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem*) const 607 { 608 return true; 609 } 610 611 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const 612 { 613 } 614 615 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const 616 { 617 } 618 619 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const 620 { 621 } 622 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 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 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 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 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 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 727 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*) 728 { 729 } 730 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 742 void WebFrameLoaderClient::didSaveToPageCache() 743 { 744 } 745 746 void WebFrameLoaderClient::didRestoreFromPageCache() 747 { 748 } 749 750 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool) 751 { 752 } 753 754 bool WebFrameLoaderClient::canCachePage() const 755 { 756 return true; 757 } 758 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 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 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 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 817 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 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 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 934 WebHistory* WebFrameLoaderClient::webHistory() const 935 { 936 if (m_webFrame != m_webFrame->webView()->topLevelFrame()) 937 return 0; 938 939 return WebHistory::sharedHistory(); 940 } 941 942 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