1 /* 2 * Copyright (C) 2010, 2011 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 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "WebFrameLoaderClient.h" 28 29 #include "AuthenticationManager.h" 30 #include "DataReference.h" 31 #include "InjectedBundleNavigationAction.h" 32 #include "InjectedBundleUserMessageCoders.h" 33 #include "PlatformCertificateInfo.h" 34 #include "PluginView.h" 35 #include "StringPairVector.h" 36 #include "WebBackForwardListProxy.h" 37 #include "WebContextMessages.h" 38 #include "WebCoreArgumentCoders.h" 39 #include "WebErrors.h" 40 #include "WebEvent.h" 41 #include "WebFrame.h" 42 #include "WebFrameNetworkingContext.h" 43 #include "WebNavigationDataStore.h" 44 #include "WebPage.h" 45 #include "WebPageProxyMessages.h" 46 #include "WebProcess.h" 47 #include "WebProcessProxyMessages.h" 48 #include <JavaScriptCore/APICast.h> 49 #include <JavaScriptCore/JSObject.h> 50 #include <WebCore/Chrome.h> 51 #include <WebCore/DOMWrapperWorld.h> 52 #include <WebCore/DocumentLoader.h> 53 #include <WebCore/FormState.h> 54 #include <WebCore/Frame.h> 55 #include <WebCore/FrameLoadRequest.h> 56 #include <WebCore/FrameView.h> 57 #include <WebCore/HTMLAppletElement.h> 58 #include <WebCore/HTMLFormElement.h> 59 #include <WebCore/HistoryItem.h> 60 #include <WebCore/MIMETypeRegistry.h> 61 #include <WebCore/MouseEvent.h> 62 #include <WebCore/NotImplemented.h> 63 #include <WebCore/Page.h> 64 #include <WebCore/PluginData.h> 65 #include <WebCore/ProgressTracker.h> 66 #include <WebCore/ResourceError.h> 67 #include <WebCore/UIEventWithKeyState.h> 68 #include <WebCore/Widget.h> 69 #include <WebCore/WindowFeatures.h> 70 71 using namespace WebCore; 72 73 namespace WebKit { 74 75 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* frame) 76 : m_frame(frame) 77 , m_hasSentResponseToPluginView(false) 78 , m_frameHasCustomRepresentation(false) 79 { 80 } 81 82 WebFrameLoaderClient::~WebFrameLoaderClient() 83 { 84 } 85 86 void WebFrameLoaderClient::frameLoaderDestroyed() 87 { 88 m_frame->invalidate(); 89 90 // Balances explicit ref() in WebFrame::createMainFrame and WebFrame::createSubframe. 91 m_frame->deref(); 92 } 93 94 bool WebFrameLoaderClient::hasHTMLView() const 95 { 96 return !m_frameHasCustomRepresentation; 97 } 98 99 bool WebFrameLoaderClient::hasWebView() const 100 { 101 return m_frame->page(); 102 } 103 104 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*) 105 { 106 notImplemented(); 107 } 108 109 void WebFrameLoaderClient::forceLayout() 110 { 111 notImplemented(); 112 } 113 114 void WebFrameLoaderClient::forceLayoutForNonHTML() 115 { 116 notImplemented(); 117 } 118 119 void WebFrameLoaderClient::setCopiesOnScroll() 120 { 121 notImplemented(); 122 } 123 124 void WebFrameLoaderClient::detachedFromParent2() 125 { 126 WebPage* webPage = m_frame->page(); 127 if (!webPage) 128 return; 129 130 RefPtr<APIObject> userData; 131 132 // Notify the bundle client. 133 webPage->injectedBundleLoaderClient().didRemoveFrameFromHierarchy(webPage, m_frame, userData); 134 135 // Notify the UIProcess. 136 webPage->send(Messages::WebPageProxy::DidRemoveFrameFromHierarchy(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); 137 138 } 139 140 void WebFrameLoaderClient::detachedFromParent3() 141 { 142 notImplemented(); 143 } 144 145 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) 146 { 147 WebPage* webPage = m_frame->page(); 148 if (!webPage) 149 return; 150 151 bool pageIsProvisionallyLoading = false; 152 if (FrameLoader* frameLoader = loader->frameLoader()) 153 pageIsProvisionallyLoading = frameLoader->provisionalDocumentLoader() == loader; 154 155 webPage->injectedBundleResourceLoadClient().didInitiateLoadForResource(webPage, m_frame, identifier, request, pageIsProvisionallyLoading); 156 webPage->send(Messages::WebPageProxy::DidInitiateLoadForResource(m_frame->frameID(), identifier, request, pageIsProvisionallyLoading)); 157 } 158 159 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) 160 { 161 WebPage* webPage = m_frame->page(); 162 if (!webPage) 163 return; 164 165 webPage->injectedBundleResourceLoadClient().willSendRequestForFrame(webPage, m_frame, identifier, request, redirectResponse); 166 167 if (request.isNull()) { 168 // FIXME: We should probably send a message saying we cancelled the request for the resource. 169 return; 170 } 171 172 webPage->send(Messages::WebPageProxy::DidSendRequestForResource(m_frame->frameID(), identifier, request, redirectResponse)); 173 } 174 175 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier) 176 { 177 return true; 178 } 179 180 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge) 181 { 182 // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet. 183 // Once we do, we might need to make sure authentication fits with our solution. 184 185 WebPage* webPage = m_frame->page(); 186 if (!webPage) 187 return; 188 189 AuthenticationManager::shared().didReceiveAuthenticationChallenge(m_frame, challenge); 190 } 191 192 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&) 193 { 194 notImplemented(); 195 } 196 197 #if USE(PROTECTION_SPACE_AUTH_CALLBACK) 198 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader*, unsigned long, const ProtectionSpace& protectionSpace) 199 { 200 // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet. 201 // Once we do, we might need to make sure authentication fits with our solution. 202 203 WebPage* webPage = m_frame->page(); 204 if (!webPage) 205 return false; 206 207 bool canAuthenticate; 208 if (!webPage->sendSync(Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame(m_frame->frameID(), protectionSpace), Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame::Reply(canAuthenticate))) 209 return false; 210 211 return canAuthenticate; 212 } 213 #endif 214 215 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response) 216 { 217 WebPage* webPage = m_frame->page(); 218 if (!webPage) 219 return; 220 221 webPage->injectedBundleResourceLoadClient().didReceiveResponseForResource(webPage, m_frame, identifier, response); 222 webPage->send(Messages::WebPageProxy::DidReceiveResponseForResource(m_frame->frameID(), identifier, response)); 223 } 224 225 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength) 226 { 227 WebPage* webPage = m_frame->page(); 228 if (!webPage) 229 return; 230 231 webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(webPage, m_frame, identifier, dataLength); 232 webPage->send(Messages::WebPageProxy::DidReceiveContentLengthForResource(m_frame->frameID(), identifier, dataLength)); 233 } 234 235 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier) 236 { 237 WebPage* webPage = m_frame->page(); 238 if (!webPage) 239 return; 240 241 webPage->injectedBundleResourceLoadClient().didFinishLoadForResource(webPage, m_frame, identifier); 242 webPage->send(Messages::WebPageProxy::DidFinishLoadForResource(m_frame->frameID(), identifier)); 243 } 244 245 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& error) 246 { 247 WebPage* webPage = m_frame->page(); 248 if (!webPage) 249 return; 250 251 webPage->injectedBundleResourceLoadClient().didFailLoadForResource(webPage, m_frame, identifier, error); 252 webPage->send(Messages::WebPageProxy::DidFailLoadForResource(m_frame->frameID(), identifier, error)); 253 } 254 255 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length) 256 { 257 notImplemented(); 258 return false; 259 } 260 261 void WebFrameLoaderClient::dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const String&) 262 { 263 notImplemented(); 264 } 265 266 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents() 267 { 268 WebPage* webPage = m_frame->page(); 269 if (!webPage) 270 return; 271 272 // Notify the bundle client. 273 webPage->injectedBundleLoaderClient().didHandleOnloadEventsForFrame(webPage, m_frame); 274 } 275 276 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad() 277 { 278 WebPage* webPage = m_frame->page(); 279 if (!webPage) 280 return; 281 282 DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader(); 283 const String& url = provisionalLoader->url().string(); 284 RefPtr<APIObject> userData; 285 286 // Notify the bundle client. 287 webPage->injectedBundleLoaderClient().didReceiveServerRedirectForProvisionalLoadForFrame(webPage, m_frame, userData); 288 289 // Notify the UIProcess. 290 webPage->send(Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame(m_frame->frameID(), url, InjectedBundleUserMessageEncoder(userData.get()))); 291 } 292 293 void WebFrameLoaderClient::dispatchDidCancelClientRedirect() 294 { 295 WebPage* webPage = m_frame->page(); 296 if (!webPage) 297 return; 298 299 // Notify the bundle client. 300 webPage->injectedBundleLoaderClient().didCancelClientRedirectForFrame(webPage, m_frame); 301 } 302 303 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double interval, double fireDate) 304 { 305 WebPage* webPage = m_frame->page(); 306 if (!webPage) 307 return; 308 309 // Notify the bundle client. 310 webPage->injectedBundleLoaderClient().willPerformClientRedirectForFrame(webPage, m_frame, url.string(), interval, fireDate); 311 } 312 313 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage() 314 { 315 WebPage* webPage = m_frame->page(); 316 if (!webPage) 317 return; 318 319 RefPtr<APIObject> userData; 320 321 // Notify the bundle client. 322 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationAnchorNavigation, userData); 323 324 // Notify the UIProcess. 325 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationAnchorNavigation, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get()))); 326 } 327 328 void WebFrameLoaderClient::dispatchDidPushStateWithinPage() 329 { 330 WebPage* webPage = m_frame->page(); 331 if (!webPage) 332 return; 333 334 RefPtr<APIObject> userData; 335 336 // Notify the bundle client. 337 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePush, userData); 338 339 // Notify the UIProcess. 340 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePush, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get()))); 341 } 342 343 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage() 344 { 345 WebPage* webPage = m_frame->page(); 346 if (!webPage) 347 return; 348 349 RefPtr<APIObject> userData; 350 351 // Notify the bundle client. 352 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStateReplace, userData); 353 354 // Notify the UIProcess. 355 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStateReplace, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get()))); 356 } 357 358 void WebFrameLoaderClient::dispatchDidPopStateWithinPage() 359 { 360 WebPage* webPage = m_frame->page(); 361 if (!webPage) 362 return; 363 364 RefPtr<APIObject> userData; 365 366 // Notify the bundle client. 367 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePop, userData); 368 369 // Notify the UIProcess. 370 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePop, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get()))); 371 } 372 373 void WebFrameLoaderClient::dispatchWillClose() 374 { 375 notImplemented(); 376 } 377 378 void WebFrameLoaderClient::dispatchDidReceiveIcon() 379 { 380 notImplemented(); 381 } 382 383 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad() 384 { 385 WebPage* webPage = m_frame->page(); 386 if (!webPage) 387 return; 388 389 webPage->findController().hideFindUI(); 390 webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame); 391 392 DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader(); 393 const String& url = provisionalLoader->url().string(); 394 RefPtr<APIObject> userData; 395 396 // Notify the bundle client. 397 webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(webPage, m_frame, userData); 398 399 String unreachableURL = provisionalLoader->unreachableURL().string(); 400 401 // Notify the UIProcess. 402 webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), url, unreachableURL, InjectedBundleUserMessageEncoder(userData.get()))); 403 } 404 405 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title) 406 { 407 WebPage* webPage = m_frame->page(); 408 if (!webPage) 409 return; 410 411 RefPtr<APIObject> userData; 412 413 // Notify the bundle client. 414 // FIXME: use direction of title. 415 webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title.string(), m_frame, userData); 416 417 // Notify the UIProcess. 418 webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title.string(), InjectedBundleUserMessageEncoder(userData.get()))); 419 } 420 421 void WebFrameLoaderClient::dispatchDidChangeIcons() 422 { 423 notImplemented(); 424 } 425 426 void WebFrameLoaderClient::dispatchDidCommitLoad() 427 { 428 WebPage* webPage = m_frame->page(); 429 if (!webPage) 430 return; 431 432 const ResourceResponse& response = m_frame->coreFrame()->loader()->documentLoader()->response(); 433 RefPtr<APIObject> userData; 434 435 // Notify the bundle client. 436 webPage->injectedBundleLoaderClient().didCommitLoadForFrame(webPage, m_frame, userData); 437 438 webPage->sandboxExtensionTracker().didCommitProvisionalLoad(m_frame); 439 440 // Notify the UIProcess. 441 442 webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), response.mimeType(), m_frameHasCustomRepresentation, PlatformCertificateInfo(response), InjectedBundleUserMessageEncoder(userData.get()))); 443 444 // Only restore the scale factor for standard frame loads (of the main frame). 445 if (m_frame->isMainFrame() && m_frame->coreFrame()->loader()->loadType() == FrameLoadTypeStandard) { 446 if (m_frame->coreFrame()->pageScaleFactor() != 1) 447 webPage->scaleWebView(1, IntPoint()); 448 } 449 } 450 451 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error) 452 { 453 WebPage* webPage = m_frame->page(); 454 if (!webPage) 455 return; 456 457 RefPtr<APIObject> userData; 458 459 // Notify the bundle client. 460 webPage->injectedBundleLoaderClient().didFailProvisionalLoadWithErrorForFrame(webPage, m_frame, error, userData); 461 462 webPage->sandboxExtensionTracker().didFailProvisionalLoad(m_frame); 463 464 // Notify the UIProcess. 465 webPage->send(Messages::WebPageProxy::DidFailProvisionalLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get()))); 466 467 // If we have a load listener, notify it. 468 if (WebFrame::LoadListener* loadListener = m_frame->loadListener()) 469 loadListener->didFailLoad(m_frame, error.isCancellation()); 470 } 471 472 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error) 473 { 474 WebPage* webPage = m_frame->page(); 475 if (!webPage) 476 return; 477 478 RefPtr<APIObject> userData; 479 480 // Notify the bundle client. 481 webPage->injectedBundleLoaderClient().didFailLoadWithErrorForFrame(webPage, m_frame, error, userData); 482 483 // Notify the UIProcess. 484 webPage->send(Messages::WebPageProxy::DidFailLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get()))); 485 486 // If we have a load listener, notify it. 487 if (WebFrame::LoadListener* loadListener = m_frame->loadListener()) 488 loadListener->didFailLoad(m_frame, error.isCancellation()); 489 } 490 491 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad() 492 { 493 WebPage* webPage = m_frame->page(); 494 if (!webPage) 495 return; 496 497 RefPtr<APIObject> userData; 498 499 // Notify the bundle client. 500 webPage->injectedBundleLoaderClient().didFinishDocumentLoadForFrame(webPage, m_frame, userData); 501 502 // Notify the UIProcess. 503 webPage->send(Messages::WebPageProxy::DidFinishDocumentLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); 504 } 505 506 void WebFrameLoaderClient::dispatchDidFinishLoad() 507 { 508 WebPage* webPage = m_frame->page(); 509 if (!webPage) 510 return; 511 512 RefPtr<APIObject> userData; 513 514 // Notify the bundle client. 515 webPage->injectedBundleLoaderClient().didFinishLoadForFrame(webPage, m_frame, userData); 516 517 // Notify the UIProcess. 518 webPage->send(Messages::WebPageProxy::DidFinishLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); 519 520 // If we have a load listener, notify it. 521 if (WebFrame::LoadListener* loadListener = m_frame->loadListener()) 522 loadListener->didFinishLoad(m_frame); 523 } 524 525 void WebFrameLoaderClient::dispatchDidFirstLayout() 526 { 527 WebPage* webPage = m_frame->page(); 528 if (!webPage) 529 return; 530 531 RefPtr<APIObject> userData; 532 533 // Notify the bundle client. 534 webPage->injectedBundleLoaderClient().didFirstLayoutForFrame(webPage, m_frame, userData); 535 536 // Notify the UIProcess. 537 webPage->send(Messages::WebPageProxy::DidFirstLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); 538 } 539 540 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout() 541 { 542 WebPage* webPage = m_frame->page(); 543 if (!webPage) 544 return; 545 546 RefPtr<APIObject> userData; 547 548 // Notify the bundle client. 549 webPage->injectedBundleLoaderClient().didFirstVisuallyNonEmptyLayoutForFrame(webPage, m_frame, userData); 550 551 // Notify the UIProcess. 552 webPage->send(Messages::WebPageProxy::DidFirstVisuallyNonEmptyLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); 553 } 554 555 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction) 556 { 557 WebPage* webPage = m_frame->page(); 558 if (!webPage) 559 return 0; 560 561 // Just call through to the chrome client. 562 Page* newPage = webPage->corePage()->chrome()->createWindow(m_frame->coreFrame(), FrameLoadRequest(m_frame->coreFrame()->document()->securityOrigin()), WindowFeatures(), navigationAction); 563 if (!newPage) 564 return 0; 565 566 return newPage->mainFrame(); 567 } 568 569 void WebFrameLoaderClient::dispatchShow() 570 { 571 WebPage* webPage = m_frame->page(); 572 if (!webPage) 573 return; 574 575 webPage->show(); 576 } 577 578 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction function, const ResourceResponse& response, const ResourceRequest& request) 579 { 580 WebPage* webPage = m_frame->page(); 581 if (!webPage) 582 return; 583 584 if (!request.url().string()) 585 return; 586 587 RefPtr<APIObject> userData; 588 589 // Notify the bundle client. 590 WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForResponse(webPage, m_frame, response, request, userData); 591 if (policy == WKBundlePagePolicyActionUse) { 592 (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse); 593 return; 594 } 595 596 uint64_t listenerID = m_frame->setUpPolicyListener(function); 597 bool receivedPolicyAction; 598 uint64_t policyAction; 599 uint64_t downloadID; 600 601 // Notify the UIProcess. 602 if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), response, request, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForResponse::Reply(receivedPolicyAction, policyAction, downloadID))) 603 return; 604 605 // We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback. 606 if (receivedPolicyAction) 607 m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID); 608 } 609 610 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName) 611 { 612 WebPage* webPage = m_frame->page(); 613 if (!webPage) 614 return; 615 616 RefPtr<APIObject> userData; 617 618 RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState); 619 620 // Notify the bundle client. 621 WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNewWindowAction(webPage, m_frame, action.get(), request, frameName, userData); 622 if (policy == WKBundlePagePolicyActionUse) { 623 (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse); 624 return; 625 } 626 627 628 uint64_t listenerID = m_frame->setUpPolicyListener(function); 629 630 // Notify the UIProcess. 631 webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), action->navigationType(), action->modifiers(), action->mouseButton(), request, frameName, listenerID, InjectedBundleUserMessageEncoder(userData.get()))); 632 } 633 634 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState) 635 { 636 WebPage* webPage = m_frame->page(); 637 if (!webPage) 638 return; 639 640 // Always ignore requests with empty URLs. 641 if (request.isEmpty()) { 642 (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyIgnore); 643 return; 644 } 645 646 RefPtr<APIObject> userData; 647 648 RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState); 649 650 // Notify the bundle client. 651 WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.get(), request, userData); 652 if (policy == WKBundlePagePolicyActionUse) { 653 (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse); 654 return; 655 } 656 657 uint64_t listenerID = m_frame->setUpPolicyListener(function); 658 bool receivedPolicyAction; 659 uint64_t policyAction; 660 uint64_t downloadID; 661 662 // Notify the UIProcess. 663 if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), action->navigationType(), action->modifiers(), action->mouseButton(), request, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(receivedPolicyAction, policyAction, downloadID))) 664 return; 665 666 // We call this synchronously because WebCore cannot gracefully handle a frame load without a synchronous navigation policy reply. 667 if (receivedPolicyAction) 668 m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID); 669 } 670 671 void WebFrameLoaderClient::cancelPolicyCheck() 672 { 673 m_frame->invalidatePolicyListener(); 674 } 675 676 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error) 677 { 678 WebPage* webPage = m_frame->page(); 679 if (!webPage) 680 return; 681 682 RefPtr<APIObject> userData; 683 684 // Notify the bundle client. 685 webPage->injectedBundlePolicyClient().unableToImplementPolicy(webPage, m_frame, error, userData); 686 687 // Notify the UIProcess. 688 webPage->send(Messages::WebPageProxy::UnableToImplementPolicy(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get()))); 689 } 690 691 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> prpFormState) 692 { 693 WebPage* webPage = m_frame->page(); 694 if (!webPage) 695 return; 696 697 // FIXME: Pass more of the form state. 698 RefPtr<FormState> formState = prpFormState; 699 700 HTMLFormElement* form = formState->form(); 701 WebFrame* sourceFrame = static_cast<WebFrameLoaderClient*>(formState->sourceFrame()->loader()->client())->webFrame(); 702 const Vector<std::pair<String, String> >& values = formState->textFieldValues(); 703 704 RefPtr<APIObject> userData; 705 webPage->injectedBundleFormClient().willSubmitForm(webPage, form, m_frame, sourceFrame, values, userData); 706 707 708 uint64_t listenerID = m_frame->setUpPolicyListener(function); 709 StringPairVector valuesVector(values); 710 711 webPage->send(Messages::WebPageProxy::WillSubmitForm(m_frame->frameID(), sourceFrame->frameID(), valuesVector, listenerID, InjectedBundleUserMessageEncoder(userData.get()))); 712 } 713 714 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*) 715 { 716 notImplemented(); 717 } 718 719 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*) 720 { 721 notImplemented(); 722 } 723 724 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error) 725 { 726 if (!m_pluginView) 727 return; 728 729 m_pluginView->manualLoadDidFail(error); 730 m_pluginView = 0; 731 m_hasSentResponseToPluginView = false; 732 } 733 734 void WebFrameLoaderClient::willChangeEstimatedProgress() 735 { 736 notImplemented(); 737 } 738 739 void WebFrameLoaderClient::didChangeEstimatedProgress() 740 { 741 notImplemented(); 742 } 743 744 void WebFrameLoaderClient::postProgressStartedNotification() 745 { 746 if (WebPage* webPage = m_frame->page()) 747 webPage->send(Messages::WebPageProxy::DidStartProgress()); 748 } 749 750 void WebFrameLoaderClient::postProgressEstimateChangedNotification() 751 { 752 if (WebPage* webPage = m_frame->page()) { 753 double progress = webPage->corePage()->progress()->estimatedProgress(); 754 webPage->send(Messages::WebPageProxy::DidChangeProgress(progress)); 755 756 } 757 } 758 759 void WebFrameLoaderClient::postProgressFinishedNotification() 760 { 761 if (WebPage* webPage = m_frame->page()) 762 webPage->send(Messages::WebPageProxy::DidFinishProgress()); 763 } 764 765 void WebFrameLoaderClient::setMainFrameDocumentReady(bool) 766 { 767 notImplemented(); 768 } 769 770 void WebFrameLoaderClient::startDownload(const ResourceRequest& request) 771 { 772 m_frame->startDownload(request); 773 } 774 775 void WebFrameLoaderClient::willChangeTitle(DocumentLoader*) 776 { 777 notImplemented(); 778 } 779 780 void WebFrameLoaderClient::didChangeTitle(DocumentLoader*) 781 { 782 notImplemented(); 783 } 784 785 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length) 786 { 787 // If we're loading a custom representation, we don't want to hand off the data to WebCore. 788 if (m_frameHasCustomRepresentation) 789 return; 790 791 if (!m_pluginView) 792 loader->commitData(data, length); 793 794 // If the document is a stand-alone media document, now is the right time to cancel the WebKit load. 795 // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>. 796 if (m_frame->coreFrame()->document()->isMediaDocument()) 797 loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response())); 798 799 // Calling commitData did not create the plug-in view. 800 if (!m_pluginView) 801 return; 802 803 if (!m_hasSentResponseToPluginView) { 804 m_pluginView->manualLoadDidReceiveResponse(loader->response()); 805 // manualLoadDidReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in 806 // setting up this stream can cause the main document load to be cancelled, setting m_pluginView 807 // to null 808 if (!m_pluginView) 809 return; 810 m_hasSentResponseToPluginView = true; 811 } 812 m_pluginView->manualLoadDidReceiveData(data, length); 813 } 814 815 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader) 816 { 817 if (!m_pluginView) { 818 committedLoad(loader, 0, 0); 819 820 if (m_frameHasCustomRepresentation) { 821 WebPage* webPage = m_frame->page(); 822 if (!webPage) 823 return; 824 825 RefPtr<SharedBuffer> mainResourceData = loader->mainResourceData(); 826 CoreIPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(mainResourceData ? mainResourceData->data() : 0), mainResourceData ? mainResourceData->size() : 0); 827 828 webPage->send(Messages::WebPageProxy::DidFinishLoadingDataForCustomRepresentation(loader->response().suggestedFilename(), dataReference)); 829 } 830 831 return; 832 } 833 834 m_pluginView->manualLoadDidFinishLoading(); 835 m_pluginView = 0; 836 m_hasSentResponseToPluginView = false; 837 } 838 839 void WebFrameLoaderClient::updateGlobalHistory() 840 { 841 WebPage* webPage = m_frame->page(); 842 if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient()) 843 return; 844 845 DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader(); 846 847 WebNavigationDataStore data; 848 data.url = loader->urlForHistory().string(); 849 // FIXME: use direction of title. 850 data.title = loader->title().string(); 851 852 WebProcess::shared().connection()->send(Messages::WebContext::DidNavigateWithNavigationData(webPage->pageID(), data, m_frame->frameID()), 0); 853 } 854 855 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks() 856 { 857 WebPage* webPage = m_frame->page(); 858 if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient()) 859 return; 860 861 DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader(); 862 ASSERT(loader->unreachableURL().isEmpty()); 863 864 // Client redirect 865 if (!loader->clientRedirectSourceForHistory().isNull()) { 866 WebProcess::shared().connection()->send(Messages::WebContext::DidPerformClientRedirect(webPage->pageID(), 867 loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_frame->frameID()), 0); 868 } 869 870 // Server redirect 871 if (!loader->serverRedirectSourceForHistory().isNull()) { 872 WebProcess::shared().connection()->send(Messages::WebContext::DidPerformServerRedirect(webPage->pageID(), 873 loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_frame->frameID()), 0); 874 } 875 } 876 877 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const 878 { 879 WebPage* webPage = m_frame->page(); 880 if (!webPage) 881 return false; 882 883 uint64_t itemID = WebBackForwardListProxy::idForItem(item); 884 if (!itemID) { 885 // We should never be considering navigating to an item that is not actually in the back/forward list. 886 ASSERT_NOT_REACHED(); 887 return false; 888 } 889 890 bool shouldGoToBackForwardListItem; 891 if (!webPage->sendSync(Messages::WebPageProxy::ShouldGoToBackForwardListItem(itemID), Messages::WebPageProxy::ShouldGoToBackForwardListItem::Reply(shouldGoToBackForwardListItem))) 892 return false; 893 894 return shouldGoToBackForwardListItem; 895 } 896 897 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const 898 { 899 return true; 900 } 901 902 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const 903 { 904 notImplemented(); 905 } 906 907 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const 908 { 909 notImplemented(); 910 } 911 912 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const 913 { 914 notImplemented(); 915 } 916 917 void WebFrameLoaderClient::didDisplayInsecureContent() 918 { 919 WebPage* webPage = m_frame->page(); 920 if (!webPage) 921 return; 922 923 RefPtr<APIObject> userData; 924 925 webPage->injectedBundleLoaderClient().didDisplayInsecureContentForFrame(webPage, m_frame, userData); 926 927 webPage->send(Messages::WebPageProxy::DidDisplayInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); 928 } 929 930 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin*, const KURL&) 931 { 932 WebPage* webPage = m_frame->page(); 933 if (!webPage) 934 return; 935 936 RefPtr<APIObject> userData; 937 938 webPage->injectedBundleLoaderClient().didRunInsecureContentForFrame(webPage, m_frame, userData); 939 940 webPage->send(Messages::WebPageProxy::DidRunInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); 941 } 942 943 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request) 944 { 945 return WebKit::cancelledError(request); 946 } 947 948 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request) 949 { 950 return WebKit::blockedError(request); 951 } 952 953 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request) 954 { 955 return WebKit::cannotShowURLError(request); 956 } 957 958 ResourceError WebFrameLoaderClient::interruptForPolicyChangeError(const ResourceRequest& request) 959 { 960 return WebKit::interruptForPolicyChangeError(request); 961 } 962 963 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response) 964 { 965 return WebKit::cannotShowMIMETypeError(response); 966 } 967 968 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response) 969 { 970 return WebKit::fileDoesNotExistError(response); 971 } 972 973 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response) 974 { 975 return WebKit::pluginWillHandleLoadError(response); 976 } 977 978 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error) 979 { 980 DEFINE_STATIC_LOCAL(const ResourceError, cancelledError, (this->cancelledError(ResourceRequest()))); 981 DEFINE_STATIC_LOCAL(const ResourceError, pluginWillHandleLoadError, (this->pluginWillHandleLoadError(ResourceResponse()))); 982 983 if (error.errorCode() == cancelledError.errorCode() && error.domain() == cancelledError.domain()) 984 return false; 985 986 if (error.errorCode() == pluginWillHandleLoadError.errorCode() && error.domain() == pluginWillHandleLoadError.domain()) 987 return false; 988 989 return true; 990 } 991 992 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest&) const 993 { 994 notImplemented(); 995 return true; 996 } 997 998 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const 999 { 1000 notImplemented(); 1001 return true; 1002 } 1003 1004 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const 1005 { 1006 return true; 1007 } 1008 1009 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const 1010 { 1011 notImplemented(); 1012 return false; 1013 } 1014 1015 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const 1016 { 1017 notImplemented(); 1018 return String(); 1019 } 1020 1021 void WebFrameLoaderClient::frameLoadCompleted() 1022 { 1023 notImplemented(); 1024 } 1025 1026 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem*) 1027 { 1028 notImplemented(); 1029 } 1030 1031 void WebFrameLoaderClient::restoreViewState() 1032 { 1033 // Inform the UI process of the scale factor. 1034 double scaleFactor = m_frame->coreFrame()->loader()->history()->currentItem()->pageScaleFactor(); 1035 m_frame->page()->send(Messages::WebPageProxy::ViewScaleFactorDidChange(scaleFactor)); 1036 1037 // FIXME: This should not be necessary. WebCore should be correctly invalidating 1038 // the view on restores from the back/forward cache. 1039 if (m_frame == m_frame->page()->mainFrame()) 1040 m_frame->page()->drawingArea()->setNeedsDisplay(m_frame->page()->bounds()); 1041 } 1042 1043 void WebFrameLoaderClient::provisionalLoadStarted() 1044 { 1045 notImplemented(); 1046 } 1047 1048 void WebFrameLoaderClient::didFinishLoad() 1049 { 1050 // If we have a load listener, notify it. 1051 if (WebFrame::LoadListener* loadListener = m_frame->loadListener()) 1052 loadListener->didFinishLoad(m_frame); 1053 } 1054 1055 void WebFrameLoaderClient::prepareForDataSourceReplacement() 1056 { 1057 notImplemented(); 1058 } 1059 1060 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& data) 1061 { 1062 return DocumentLoader::create(request, data); 1063 } 1064 1065 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url) 1066 { 1067 WebPage* webPage = m_frame->page(); 1068 if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient()) 1069 return; 1070 1071 // FIXME: use direction of title. 1072 WebProcess::shared().connection()->send(Messages::WebContext::DidUpdateHistoryTitle(webPage->pageID(), 1073 title.string(), url.string(), m_frame->frameID()), 0); 1074 } 1075 1076 String WebFrameLoaderClient::userAgent(const KURL&) 1077 { 1078 WebPage* webPage = m_frame->page(); 1079 if (!webPage) 1080 return String(); 1081 1082 return webPage->userAgent(); 1083 } 1084 1085 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame*) 1086 { 1087 } 1088 1089 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*) 1090 { 1091 WebPage* webPage = m_frame->page(); 1092 bool isMainFrame = webPage->mainFrame() == m_frame; 1093 1094 const String& mimeType = m_frame->coreFrame()->loader()->documentLoader()->response().mimeType(); 1095 m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForMIMEType(mimeType); 1096 } 1097 1098 void WebFrameLoaderClient::transitionToCommittedForNewPage() 1099 { 1100 WebPage* webPage = m_frame->page(); 1101 Color backgroundColor = webPage->drawsTransparentBackground() ? Color::transparent : Color::white; 1102 1103 bool isMainFrame = webPage->mainFrame() == m_frame; 1104 1105 #if ENABLE(TILED_BACKING_STORE) 1106 IntSize currentVisibleContentSize = m_frame->coreFrame()->view() ? m_frame->coreFrame()->view()->actualVisibleContentRect().size() : IntSize(); 1107 m_frame->coreFrame()->createView(webPage->size(), backgroundColor, false, webPage->resizesToContentsLayoutSize(), isMainFrame && webPage->resizesToContentsEnabled()); 1108 1109 if (isMainFrame && webPage->resizesToContentsEnabled()) { 1110 m_frame->coreFrame()->view()->setDelegatesScrolling(true); 1111 m_frame->coreFrame()->view()->setPaintsEntireContents(true); 1112 } 1113 1114 // The HistoryController will update the scroll position later if needed. 1115 m_frame->coreFrame()->view()->setActualVisibleContentRect(IntRect(IntPoint::zero(), currentVisibleContentSize)); 1116 #else 1117 const String& mimeType = m_frame->coreFrame()->loader()->documentLoader()->response().mimeType(); 1118 m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForMIMEType(mimeType); 1119 1120 m_frame->coreFrame()->createView(webPage->size(), backgroundColor, false, IntSize(), false); 1121 #endif 1122 1123 m_frame->coreFrame()->view()->setTransparent(!webPage->drawsBackground()); 1124 } 1125 1126 void WebFrameLoaderClient::didSaveToPageCache() 1127 { 1128 WebPage* webPage = m_frame->page(); 1129 if (!webPage) 1130 return; 1131 1132 if (m_frame->isMainFrame()) 1133 return; 1134 1135 webPage->send(Messages::WebPageProxy::DidSaveFrameToPageCache(m_frame->frameID())); 1136 } 1137 1138 void WebFrameLoaderClient::didRestoreFromPageCache() 1139 { 1140 WebPage* webPage = m_frame->page(); 1141 if (!webPage) 1142 return; 1143 1144 if (m_frame->isMainFrame()) 1145 return; 1146 1147 WebFrame* parentFrame = static_cast<WebFrameLoaderClient*>(m_frame->coreFrame()->tree()->parent()->loader()->client())->webFrame(); 1148 webPage->send(Messages::WebPageProxy::DidRestoreFrameFromPageCache(m_frame->frameID(), parentFrame->frameID())); 1149 } 1150 1151 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool value) 1152 { 1153 WebPage* webPage = m_frame->page(); 1154 if (!webPage) 1155 return; 1156 1157 webPage->send(Messages::WebPageProxy::FrameDidBecomeFrameSet(m_frame->frameID(), value)); 1158 } 1159 1160 bool WebFrameLoaderClient::canCachePage() const 1161 { 1162 // We cannot cache frames that have custom representations because they are 1163 // rendered in the UIProcess. 1164 return !m_frameHasCustomRepresentation; 1165 } 1166 1167 void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response) 1168 { 1169 m_frame->convertHandleToDownload(handle, request, initialRequest, response); 1170 } 1171 1172 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, 1173 const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) 1174 { 1175 WebPage* webPage = m_frame->page(); 1176 1177 RefPtr<WebFrame> subframe = WebFrame::createSubframe(webPage, name, ownerElement); 1178 1179 Frame* coreSubframe = subframe->coreFrame(); 1180 1181 // The creation of the frame may have run arbitrary JavaScript that removed it from the page already. 1182 m_frame->coreFrame()->loader()->loadURLIntoChildFrame(url, referrer, coreSubframe); 1183 1184 // The frame's onload handler may have removed it from the document. 1185 if (!coreSubframe->tree()->parent()) 1186 return 0; 1187 1188 return coreSubframe; 1189 } 1190 1191 void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*) 1192 { 1193 notImplemented(); 1194 } 1195 1196 void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*) 1197 { 1198 notImplemented(); 1199 } 1200 1201 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement* pluginElement, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually) 1202 { 1203 ASSERT(paramNames.size() == paramValues.size()); 1204 1205 WebPage* webPage = m_frame->page(); 1206 ASSERT(webPage); 1207 1208 Plugin::Parameters parameters; 1209 parameters.url = url; 1210 parameters.names = paramNames; 1211 parameters.values = paramValues; 1212 parameters.mimeType = mimeType; 1213 parameters.loadManually = loadManually; 1214 1215 // <rdar://problem/8440903>: AppleConnect has a bug where it does not 1216 // understand the parameter names specified in the <object> element that 1217 // embeds its plug-in. This hack works around the issue by converting the 1218 // parameter names to lowercase before passing them to the plug-in. 1219 // FIXME: This workaround should be dependent on site-specific quirks being 1220 // enabled. This requires adding this setting to WebKit2's WebPreferences 1221 // implementation. See <https://bugs.webkit.org/show_bug.cgi?id=46076>. 1222 if (equalIgnoringCase(mimeType, "application/x-snkp")) { 1223 for (size_t i = 0; i < paramNames.size(); ++i) 1224 parameters.names[i] = paramNames[i].lower(); 1225 } 1226 1227 #if PLUGIN_ARCHITECTURE(X11) 1228 if (equalIgnoringCase(mimeType, "application/x-shockwave-flash")) { 1229 // Currently we don't support transparency and windowed mode. 1230 // Inject wmode=opaque to make Flash work in these conditions. 1231 size_t wmodeIndex = parameters.names.find("wmode"); 1232 if (wmodeIndex == -1) { 1233 parameters.names.append("wmode"); 1234 parameters.values.append("opaque"); 1235 } else if (equalIgnoringCase(parameters.values[wmodeIndex], "window")) 1236 parameters.values[wmodeIndex] = "opaque"; 1237 } 1238 #endif 1239 1240 RefPtr<Plugin> plugin = webPage->createPlugin(parameters); 1241 if (!plugin) 1242 return 0; 1243 1244 return PluginView::create(pluginElement, plugin.release(), parameters); 1245 } 1246 1247 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget) 1248 { 1249 ASSERT(!m_pluginView); 1250 ASSERT(pluginWidget); 1251 1252 m_pluginView = static_cast<PluginView*>(pluginWidget); 1253 } 1254 1255 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* appletElement, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues) 1256 { 1257 return createPlugin(pluginSize, appletElement, KURL(), paramNames, paramValues, "application/x-java-applet", false); 1258 } 1259 1260 static bool pluginSupportsExtension(PluginData* pluginData, const String& extension) 1261 { 1262 ASSERT(extension.lower() == extension); 1263 1264 for (size_t i = 0; i < pluginData->mimes().size(); ++i) { 1265 const MimeClassInfo& mimeClassInfo = pluginData->mimes()[i]; 1266 1267 if (mimeClassInfo.extensions.contains(extension)) 1268 return true; 1269 } 1270 return false; 1271 } 1272 1273 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages) 1274 { 1275 // FIXME: This should be merged with WebCore::FrameLoader::defaultObjectContentType when the plugin code 1276 // is consolidated. 1277 1278 String mimeType = mimeTypeIn; 1279 if (mimeType.isEmpty()) { 1280 String extension = url.path().substring(url.path().reverseFind('.') + 1).lower(); 1281 1282 // Try to guess the MIME type from the extension. 1283 mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension); 1284 1285 if (mimeType.isEmpty()) { 1286 // Check if there's a plug-in around that can handle the extension. 1287 if (WebPage* webPage = m_frame->page()) { 1288 if (PluginData* pluginData = webPage->corePage()->pluginData()) { 1289 if (pluginSupportsExtension(pluginData, extension)) 1290 return ObjectContentNetscapePlugin; 1291 } 1292 } 1293 } 1294 } 1295 1296 if (mimeType.isEmpty()) 1297 return ObjectContentFrame; 1298 1299 bool plugInSupportsMIMEType = false; 1300 if (WebPage* webPage = m_frame->page()) { 1301 if (PluginData* pluginData = webPage->corePage()->pluginData()) { 1302 if (pluginData->supportsMimeType(mimeType)) 1303 plugInSupportsMIMEType = true; 1304 } 1305 } 1306 1307 if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType)) 1308 return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? ObjectContentNetscapePlugin : ObjectContentImage; 1309 1310 if (plugInSupportsMIMEType) 1311 return ObjectContentNetscapePlugin; 1312 1313 if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType)) 1314 return ObjectContentFrame; 1315 1316 return ObjectContentNone; 1317 } 1318 1319 String WebFrameLoaderClient::overrideMediaType() const 1320 { 1321 notImplemented(); 1322 return String(); 1323 } 1324 1325 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world) 1326 { 1327 WebPage* webPage = m_frame->page(); 1328 if (!webPage) 1329 return; 1330 1331 webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(webPage, m_frame, world); 1332 } 1333 1334 void WebFrameLoaderClient::documentElementAvailable() 1335 { 1336 notImplemented(); 1337 } 1338 1339 void WebFrameLoaderClient::didPerformFirstNavigation() const 1340 { 1341 notImplemented(); 1342 } 1343 1344 void WebFrameLoaderClient::registerForIconNotification(bool listen) 1345 { 1346 notImplemented(); 1347 } 1348 1349 #if PLATFORM(MAC) 1350 1351 RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject() 1352 { 1353 return m_frame->page()->accessibilityRemoteObject(); 1354 } 1355 1356 #if ENABLE(MAC_JAVA_BRIDGE) 1357 jobject WebFrameLoaderClient::javaApplet(NSView*) { return 0; } 1358 #endif 1359 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const 1360 { 1361 return response; 1362 } 1363 1364 #endif 1365 #if USE(CFNETWORK) 1366 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, const unsigned char* data, unsigned long long length) 1367 { 1368 return true; 1369 } 1370 1371 #endif 1372 1373 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& /*mimeType*/) const 1374 { 1375 notImplemented(); 1376 return false; 1377 } 1378 1379 void WebFrameLoaderClient::didChangeScrollOffset() 1380 { 1381 WebPage* webPage = m_frame->page(); 1382 if (!webPage) 1383 return; 1384 1385 if (!m_frame->isMainFrame()) 1386 return; 1387 1388 // If this is called when tearing down a FrameView, the WebCore::Frame's 1389 // current FrameView will be null. 1390 if (!m_frame->coreFrame()->view()) 1391 return; 1392 1393 webPage->didChangeScrollOffsetForMainFrame(); 1394 } 1395 1396 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext() 1397 { 1398 return WebFrameNetworkingContext::create(m_frame->coreFrame()); 1399 } 1400 1401 } // namespace WebKit 1402