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 72using namespace WebCore; 73using namespace HTMLNames; 74 75static WebDataSource* getWebDataSource(DocumentLoader* loader) 76{ 77 return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0; 78} 79 80WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* webFrame) 81 : m_webFrame(webFrame) 82 , m_manualLoader(0) 83 , m_hasSentResponseToPlugin(false) 84{ 85 ASSERT_ARG(webFrame, webFrame); 86} 87 88WebFrameLoaderClient::~WebFrameLoaderClient() 89{ 90} 91 92bool WebFrameLoaderClient::hasWebView() const 93{ 94 return m_webFrame->webView(); 95} 96 97void 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 114void 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 125bool 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 143void 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 164void 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 175void 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 204void 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 215void 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 225void 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 235void 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 246void WebFrameLoaderClient::dispatchDidLoadResourceByXMLHttpRequest(unsigned long, const ScriptString&) 247{ 248} 249 250bool 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 269void 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 277void 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 285void 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 293void 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 301void 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 309void 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 323void 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 337void 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} 350void 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 358void WebFrameLoaderClient::dispatchDidReceiveIcon() 359{ 360 m_webFrame->webView()->dispatchDidReceiveIconFromWebFrame(m_webFrame); 361} 362 363void 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 371void 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 379void 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 387void 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 395void 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 403void 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 411void 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 419Frame* 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 439void 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 447void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*) 448{ 449} 450 451void 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 461void 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 468void 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 475void 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 482void 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 505void 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 521void 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 536void 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 561void 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 603bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const 604{ 605 return true; 606} 607 608void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const 609{ 610} 611 612void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const 613{ 614} 615 616void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const 617{ 618} 619 620void 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 634void 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 650PassRefPtr<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 660void 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 695void 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 711void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*) 712{ 713} 714 715void 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 726bool WebFrameLoaderClient::canCachePage() const 727{ 728 return true; 729} 730 731PassRefPtr<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 740PassRefPtr<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 762void 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 821PassRefPtr<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 869void 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 879WebHistory* WebFrameLoaderClient::webHistory() const 880{ 881 if (m_webFrame != m_webFrame->webView()->topLevelFrame()) 882 return 0; 883 884 return WebHistory::sharedHistory(); 885} 886 887bool 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