1 /* 2 * Copyright (C) 2009, 2012 Google Inc. All rights reserved. 3 * Copyright (C) 2011 Apple Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include "config.h" 33 #include "FrameLoaderClientImpl.h" 34 35 #include "HTMLNames.h" 36 #include "core/dom/Document.h" 37 #include "core/dom/MessageEvent.h" 38 #include "core/dom/MouseEvent.h" 39 #include "core/history/HistoryItem.h" 40 #include "core/html/HTMLAppletElement.h" 41 #include "core/html/HTMLFormElement.h" // needed by core/loader/FormState.h 42 #include "core/loader/DocumentLoader.h" 43 #include "core/loader/FormState.h" 44 #include "core/loader/FrameLoadRequest.h" 45 #include "core/loader/FrameLoader.h" 46 #include "core/loader/ProgressTracker.h" 47 #include "core/loader/ResourceLoader.h" 48 #include "core/page/Chrome.h" 49 #include "core/page/EventHandler.h" 50 #include "core/page/FrameView.h" 51 #include "core/page/Page.h" 52 #include "core/platform/MIMETypeRegistry.h" 53 #include "core/platform/mediastream/RTCPeerConnectionHandler.h" 54 #include "core/platform/network/HTTPParsers.h" 55 #include "core/plugins/PluginData.h" 56 #include "core/rendering/HitTestResult.h" 57 #include <v8.h> 58 #include "WebAutofillClient.h" 59 #include "WebCachedURLRequest.h" 60 #include "WebDOMEvent.h" 61 #include "WebDataSourceImpl.h" 62 #include "WebDevToolsAgentPrivate.h" 63 #include "WebDocument.h" 64 #include "WebFormElement.h" 65 #include "WebFrameClient.h" 66 #include "WebFrameImpl.h" 67 #include "WebNode.h" 68 #include "WebPermissionClient.h" 69 #include "WebPlugin.h" 70 #include "WebPluginContainerImpl.h" 71 #include "WebPluginLoadObserver.h" 72 #include "WebPluginParams.h" 73 #include "WebSecurityOrigin.h" 74 #include "WebViewClient.h" 75 #include "WebViewImpl.h" 76 #include "bindings/v8/ScriptController.h" 77 #include "core/dom/UserGestureIndicator.h" 78 #include "core/page/Settings.h" 79 #include "core/page/WindowFeatures.h" 80 #include "core/platform/chromium/support/WrappedResourceRequest.h" 81 #include "core/platform/chromium/support/WrappedResourceResponse.h" 82 #include "core/platform/network/SocketStreamHandleInternal.h" 83 #include "public/platform/Platform.h" 84 #include "public/platform/WebMimeRegistry.h" 85 #include "public/platform/WebSocketStreamHandle.h" 86 #include "public/platform/WebURL.h" 87 #include "public/platform/WebURLError.h" 88 #include "public/platform/WebVector.h" 89 #include "wtf/StringExtras.h" 90 #include "wtf/text/CString.h" 91 #include "wtf/text/WTFString.h" 92 93 using namespace WebCore; 94 95 namespace WebKit { 96 97 // Domain for internal error codes. 98 static const char internalErrorDomain[] = "WebKit"; 99 100 // An internal error code. Used to note a policy change error resulting from 101 // dispatchDecidePolicyForMIMEType not passing the PolicyUse option. 102 enum { 103 PolicyChangeError = -10000, 104 }; 105 106 FrameLoaderClientImpl::FrameLoaderClientImpl(WebFrameImpl* frame) 107 : m_webFrame(frame) 108 { 109 } 110 111 FrameLoaderClientImpl::~FrameLoaderClientImpl() 112 { 113 } 114 115 void FrameLoaderClientImpl::frameLoaderDestroyed() 116 { 117 // When the WebFrame was created, it had an extra reference given to it on 118 // behalf of the Frame. Since the WebFrame owns us, this extra ref also 119 // serves to keep us alive until the FrameLoader is done with us. The 120 // FrameLoader calls this method when it's going away. Therefore, we balance 121 // out that extra reference, which may cause 'this' to be deleted. 122 ASSERT(!m_webFrame->frame()); 123 m_webFrame->deref(); 124 } 125 126 void FrameLoaderClientImpl::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*) 127 { 128 if (m_webFrame->client()) 129 m_webFrame->client()->didClearWindowObject(m_webFrame); 130 } 131 132 void FrameLoaderClientImpl::documentElementAvailable() 133 { 134 if (m_webFrame->client()) 135 m_webFrame->client()->didCreateDocumentElement(m_webFrame); 136 } 137 138 void FrameLoaderClientImpl::didExhaustMemoryAvailableForScript() 139 { 140 if (m_webFrame->client()) 141 m_webFrame->client()->didExhaustMemoryAvailableForScript(m_webFrame); 142 } 143 144 void FrameLoaderClientImpl::didCreateScriptContext(v8::Handle<v8::Context> context, int extensionGroup, int worldId) 145 { 146 WebViewImpl* webview = m_webFrame->viewImpl(); 147 if (webview->devToolsAgentPrivate()) 148 webview->devToolsAgentPrivate()->didCreateScriptContext(m_webFrame, worldId); 149 if (m_webFrame->client()) 150 m_webFrame->client()->didCreateScriptContext(m_webFrame, context, extensionGroup, worldId); 151 } 152 153 void FrameLoaderClientImpl::willReleaseScriptContext(v8::Handle<v8::Context> context, int worldId) 154 { 155 if (m_webFrame->client()) 156 m_webFrame->client()->willReleaseScriptContext(m_webFrame, context, worldId); 157 } 158 159 bool FrameLoaderClientImpl::allowScriptExtension(const String& extensionName, 160 int extensionGroup, 161 int worldId) 162 { 163 WebViewImpl* webview = m_webFrame->viewImpl(); 164 if (webview && webview->permissionClient()) 165 return webview->permissionClient()->allowScriptExtension(m_webFrame, extensionName, extensionGroup, worldId); 166 167 return true; 168 } 169 170 void FrameLoaderClientImpl::didChangeScrollOffset() 171 { 172 if (m_webFrame->client()) 173 m_webFrame->client()->didChangeScrollOffset(m_webFrame); 174 } 175 176 bool FrameLoaderClientImpl::allowScript(bool enabledPerSettings) 177 { 178 WebViewImpl* webview = m_webFrame->viewImpl(); 179 if (webview && webview->permissionClient()) 180 return webview->permissionClient()->allowScript(m_webFrame, enabledPerSettings); 181 182 return enabledPerSettings; 183 } 184 185 bool FrameLoaderClientImpl::allowScriptFromSource(bool enabledPerSettings, const KURL& scriptURL) 186 { 187 WebViewImpl* webview = m_webFrame->viewImpl(); 188 if (webview && webview->permissionClient()) 189 return webview->permissionClient()->allowScriptFromSource(m_webFrame, enabledPerSettings, scriptURL); 190 191 return enabledPerSettings; 192 } 193 194 bool FrameLoaderClientImpl::allowPlugins(bool enabledPerSettings) 195 { 196 WebViewImpl* webview = m_webFrame->viewImpl(); 197 if (webview && webview->permissionClient()) 198 return webview->permissionClient()->allowPlugins(m_webFrame, enabledPerSettings); 199 200 return enabledPerSettings; 201 } 202 203 bool FrameLoaderClientImpl::allowImage(bool enabledPerSettings, const KURL& imageURL) 204 { 205 WebViewImpl* webview = m_webFrame->viewImpl(); 206 if (webview && webview->permissionClient()) 207 return webview->permissionClient()->allowImage(m_webFrame, enabledPerSettings, imageURL); 208 209 return enabledPerSettings; 210 } 211 212 bool FrameLoaderClientImpl::allowDisplayingInsecureContent(bool enabledPerSettings, SecurityOrigin* context, const KURL& url) 213 { 214 WebViewImpl* webview = m_webFrame->viewImpl(); 215 if (webview && webview->permissionClient()) 216 return webview->permissionClient()->allowDisplayingInsecureContent(m_webFrame, enabledPerSettings, WebSecurityOrigin(context), WebURL(url)); 217 218 return enabledPerSettings; 219 } 220 221 bool FrameLoaderClientImpl::allowRunningInsecureContent(bool enabledPerSettings, SecurityOrigin* context, const KURL& url) 222 { 223 WebViewImpl* webview = m_webFrame->viewImpl(); 224 if (webview && webview->permissionClient()) 225 return webview->permissionClient()->allowRunningInsecureContent(m_webFrame, enabledPerSettings, WebSecurityOrigin(context), WebURL(url)); 226 227 return enabledPerSettings; 228 } 229 230 void FrameLoaderClientImpl::didNotAllowScript() 231 { 232 WebViewImpl* webview = m_webFrame->viewImpl(); 233 if (webview && webview->permissionClient()) 234 webview->permissionClient()->didNotAllowScript(m_webFrame); 235 } 236 237 void FrameLoaderClientImpl::didNotAllowPlugins() 238 { 239 WebViewImpl* webview = m_webFrame->viewImpl(); 240 if (webview && webview->permissionClient()) 241 webview->permissionClient()->didNotAllowPlugins(m_webFrame); 242 243 } 244 245 bool FrameLoaderClientImpl::hasWebView() const 246 { 247 return m_webFrame->viewImpl(); 248 } 249 250 bool FrameLoaderClientImpl::hasFrameView() const 251 { 252 // The Mac port has this notion of a WebFrameView, which seems to be 253 // some wrapper around an NSView. Since our equivalent is HWND, I guess 254 // we have a "frameview" whenever we have the toplevel HWND. 255 return m_webFrame->viewImpl(); 256 } 257 258 void FrameLoaderClientImpl::detachedFromParent() 259 { 260 // Close down the proxy. The purpose of this change is to make the 261 // call to ScriptController::clearWindowShell a no-op when called from 262 // Frame::pageDestroyed. Without this change, this call to clearWindowShell 263 // will cause a crash. If you remove/modify this, just ensure that you can 264 // go to a page and then navigate to a new page without getting any asserts 265 // or crashes. 266 m_webFrame->frame()->script()->clearForClose(); 267 268 // Alert the client that the frame is being detached. This is the last 269 // chance we have to communicate with the client. 270 if (m_webFrame->client()) 271 m_webFrame->client()->frameDetached(m_webFrame); 272 273 // Stop communicating with the WebFrameClient at this point since we are no 274 // longer associated with the Page. 275 m_webFrame->setClient(0); 276 } 277 278 void FrameLoaderClientImpl::dispatchWillRequestAfterPreconnect(ResourceRequest& request) 279 { 280 if (m_webFrame->client()) { 281 WrappedResourceRequest webreq(request); 282 m_webFrame->client()->willRequestAfterPreconnect(m_webFrame, webreq); 283 } 284 } 285 286 void FrameLoaderClientImpl::dispatchWillSendRequest( 287 DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, 288 const ResourceResponse& redirectResponse) 289 { 290 // Give the WebFrameClient a crack at the request. 291 if (m_webFrame->client()) { 292 WrappedResourceRequest webreq(request); 293 WrappedResourceResponse webresp(redirectResponse); 294 m_webFrame->client()->willSendRequest( 295 m_webFrame, identifier, webreq, webresp); 296 } 297 } 298 299 void FrameLoaderClientImpl::dispatchDidReceiveResponse(DocumentLoader* loader, 300 unsigned long identifier, 301 const ResourceResponse& response) 302 { 303 if (m_webFrame->client()) { 304 WrappedResourceResponse webresp(response); 305 m_webFrame->client()->didReceiveResponse(m_webFrame, identifier, webresp); 306 } 307 } 308 void FrameLoaderClientImpl::dispatchDidChangeResourcePriority(unsigned long identifier, 309 ResourceLoadPriority priority) 310 { 311 if (m_webFrame->client()) 312 m_webFrame->client()->didChangeResourcePriority(m_webFrame, identifier, static_cast<WebKit::WebURLRequest::Priority>(priority)); 313 } 314 315 // Called when a particular resource load completes 316 void FrameLoaderClientImpl::dispatchDidFinishLoading(DocumentLoader* loader, 317 unsigned long identifier) 318 { 319 if (m_webFrame->client()) 320 m_webFrame->client()->didFinishResourceLoad(m_webFrame, identifier); 321 } 322 323 void FrameLoaderClientImpl::dispatchDidFinishDocumentLoad() 324 { 325 if (m_webFrame->client()) 326 m_webFrame->client()->didFinishDocumentLoad(m_webFrame); 327 } 328 329 void FrameLoaderClientImpl::dispatchDidLoadResourceFromMemoryCache( 330 DocumentLoader* loader, 331 const ResourceRequest& request, 332 const ResourceResponse& response, 333 int length) 334 { 335 if (m_webFrame->client()) { 336 WrappedResourceRequest webreq(request); 337 WrappedResourceResponse webresp(response); 338 m_webFrame->client()->didLoadResourceFromMemoryCache( 339 m_webFrame, webreq, webresp); 340 } 341 } 342 343 void FrameLoaderClientImpl::dispatchDidHandleOnloadEvents() 344 { 345 if (m_webFrame->client()) 346 m_webFrame->client()->didHandleOnloadEvents(m_webFrame); 347 } 348 349 void FrameLoaderClientImpl::dispatchDidReceiveServerRedirectForProvisionalLoad() 350 { 351 if (m_webFrame->client()) 352 m_webFrame->client()->didReceiveServerRedirectForProvisionalLoad(m_webFrame); 353 } 354 355 void FrameLoaderClientImpl::dispatchDidNavigateWithinPage() 356 { 357 bool isNewNavigation; 358 m_webFrame->viewImpl()->didCommitLoad(&isNewNavigation, true); 359 if (m_webFrame->client()) 360 m_webFrame->client()->didNavigateWithinPage(m_webFrame, isNewNavigation); 361 } 362 363 void FrameLoaderClientImpl::dispatchWillClose() 364 { 365 if (m_webFrame->client()) 366 m_webFrame->client()->willClose(m_webFrame); 367 } 368 369 void FrameLoaderClientImpl::dispatchDidStartProvisionalLoad() 370 { 371 if (m_webFrame->client()) 372 m_webFrame->client()->didStartProvisionalLoad(m_webFrame); 373 } 374 375 void FrameLoaderClientImpl::dispatchDidReceiveTitle(const StringWithDirection& title) 376 { 377 if (m_webFrame->client()) 378 m_webFrame->client()->didReceiveTitle(m_webFrame, title.string(), title.direction() == LTR ? WebTextDirectionLeftToRight : WebTextDirectionRightToLeft); 379 } 380 381 void FrameLoaderClientImpl::dispatchDidChangeIcons(WebCore::IconType type) 382 { 383 if (m_webFrame->client()) 384 m_webFrame->client()->didChangeIcon(m_webFrame, static_cast<WebIconURL::Type>(type)); 385 } 386 387 void FrameLoaderClientImpl::dispatchDidCommitLoad() 388 { 389 WebViewImpl* webview = m_webFrame->viewImpl(); 390 bool isNewNavigation; 391 webview->didCommitLoad(&isNewNavigation, false); 392 393 if (m_webFrame->client()) 394 m_webFrame->client()->didCommitProvisionalLoad(m_webFrame, isNewNavigation); 395 } 396 397 void FrameLoaderClientImpl::dispatchDidFailProvisionalLoad( 398 const ResourceError& error) 399 { 400 401 // If a policy change occured, then we do not want to inform the plugin 402 // delegate. See http://b/907789 for details. FIXME: This means the 403 // plugin won't receive NPP_URLNotify, which seems like it could result in 404 // a memory leak in the plugin!! 405 if (error.domain() == internalErrorDomain 406 && error.errorCode() == PolicyChangeError) { 407 m_webFrame->didFail(ResourceError::cancelledError(error.failingURL()), true); 408 return; 409 } 410 411 OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver(); 412 m_webFrame->didFail(error, true); 413 if (observer) 414 observer->didFailLoading(error); 415 } 416 417 void FrameLoaderClientImpl::dispatchDidFailLoad(const ResourceError& error) 418 { 419 OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver(); 420 m_webFrame->didFail(error, false); 421 if (observer) 422 observer->didFailLoading(error); 423 424 // Don't clear the redirect chain, this will happen in the middle of client 425 // redirects, and we need the context. The chain will be cleared when the 426 // provisional load succeeds or fails, not the "real" one. 427 } 428 429 void FrameLoaderClientImpl::dispatchDidFinishLoad() 430 { 431 OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver(); 432 433 if (m_webFrame->client()) 434 m_webFrame->client()->didFinishLoad(m_webFrame); 435 436 if (observer) 437 observer->didFinishLoading(); 438 439 // Don't clear the redirect chain, this will happen in the middle of client 440 // redirects, and we need the context. The chain will be cleared when the 441 // provisional load succeeds or fails, not the "real" one. 442 } 443 444 void FrameLoaderClientImpl::dispatchDidLayout(LayoutMilestones milestones) 445 { 446 if (!m_webFrame->client()) 447 return; 448 449 if (milestones & DidFirstLayout) 450 m_webFrame->client()->didFirstLayout(m_webFrame); 451 if (milestones & DidFirstVisuallyNonEmptyLayout) 452 m_webFrame->client()->didFirstVisuallyNonEmptyLayout(m_webFrame); 453 } 454 455 NavigationPolicy FrameLoaderClientImpl::decidePolicyForNavigation(const ResourceRequest& request, DocumentLoader* loader, NavigationPolicy policy) 456 { 457 if (!m_webFrame->client()) 458 return NavigationPolicyIgnore; 459 WebDataSourceImpl* ds = WebDataSourceImpl::fromDocumentLoader(loader); 460 WebNavigationPolicy webPolicy = m_webFrame->client()->decidePolicyForNavigation(m_webFrame, ds->extraData(), WrappedResourceRequest(request), 461 ds->navigationType(), static_cast<WebNavigationPolicy>(policy), ds->isRedirect()); 462 return static_cast<NavigationPolicy>(webPolicy); 463 } 464 465 bool FrameLoaderClientImpl::shouldAbortNavigationAfterUrlResolve(const KURL& base, const String& fragment, const KURL& result) { 466 if (!m_webFrame->client()) 467 return false; 468 return m_webFrame->client()->shouldAbortNavigationAfterUrlResolve(base, fragment, result); 469 } 470 471 void FrameLoaderClientImpl::dispatchWillRequestResource(FetchRequest* request) 472 { 473 if (m_webFrame->client()) { 474 WebCachedURLRequest urlRequest(request); 475 m_webFrame->client()->willRequestResource(m_webFrame, urlRequest); 476 } 477 } 478 479 void FrameLoaderClientImpl::dispatchWillSendSubmitEvent(PassRefPtr<FormState> prpFormState) 480 { 481 if (m_webFrame->client()) 482 m_webFrame->client()->willSendSubmitEvent(m_webFrame, WebFormElement(prpFormState->form())); 483 } 484 485 void FrameLoaderClientImpl::dispatchWillSubmitForm(PassRefPtr<FormState> formState) 486 { 487 if (m_webFrame->client()) 488 m_webFrame->client()->willSubmitForm(m_webFrame, WebFormElement(formState->form())); 489 } 490 491 void FrameLoaderClientImpl::postProgressStartedNotification() 492 { 493 WebViewImpl* webview = m_webFrame->viewImpl(); 494 if (webview && webview->client()) 495 webview->client()->didStartLoading(); 496 } 497 498 void FrameLoaderClientImpl::postProgressEstimateChangedNotification() 499 { 500 WebViewImpl* webview = m_webFrame->viewImpl(); 501 if (webview && webview->client()) { 502 webview->client()->didChangeLoadProgress( 503 m_webFrame, m_webFrame->frame()->page()->progress()->estimatedProgress()); 504 } 505 } 506 507 void FrameLoaderClientImpl::postProgressFinishedNotification() 508 { 509 // FIXME: why might the webview be null? http://b/1234461 510 WebViewImpl* webview = m_webFrame->viewImpl(); 511 if (webview && webview->client()) 512 webview->client()->didStopLoading(); 513 } 514 515 void FrameLoaderClientImpl::loadURLExternally(const ResourceRequest& request, NavigationPolicy policy, const String& suggestedName) 516 { 517 if (m_webFrame->client()) { 518 WrappedResourceRequest webreq(request); 519 m_webFrame->client()->loadURLExternally( 520 m_webFrame, webreq, static_cast<WebNavigationPolicy>(policy), suggestedName); 521 } 522 } 523 524 bool FrameLoaderClientImpl::shouldGoToHistoryItem(HistoryItem* item) const 525 { 526 const KURL& url = item->url(); 527 if (!url.protocolIs(backForwardNavigationScheme)) 528 return true; 529 530 // Else, we'll punt this history navigation to the embedder. It is 531 // necessary that we intercept this here, well before the FrameLoader 532 // has made any state changes for this history traversal. 533 534 bool ok; 535 int offset = url.lastPathComponent().toIntStrict(&ok); 536 if (!ok) { 537 ASSERT_NOT_REACHED(); 538 return false; 539 } 540 541 WebViewImpl* webview = m_webFrame->viewImpl(); 542 if (webview->client()) 543 webview->client()->navigateBackForwardSoon(offset); 544 545 return false; 546 } 547 548 bool FrameLoaderClientImpl::shouldStopLoadingForHistoryItem(HistoryItem* targetItem) const 549 { 550 // Don't stop loading for pseudo-back-forward URLs, since they will get 551 // translated and then pass through again. 552 const KURL& url = targetItem->url(); 553 return !url.protocolIs(backForwardNavigationScheme); 554 } 555 556 void FrameLoaderClientImpl::didAccessInitialDocument() 557 { 558 if (m_webFrame->client()) 559 m_webFrame->client()->didAccessInitialDocument(m_webFrame); 560 } 561 562 void FrameLoaderClientImpl::didDisownOpener() 563 { 564 if (m_webFrame->client()) 565 m_webFrame->client()->didDisownOpener(m_webFrame); 566 } 567 568 void FrameLoaderClientImpl::didDisplayInsecureContent() 569 { 570 if (m_webFrame->client()) 571 m_webFrame->client()->didDisplayInsecureContent(m_webFrame); 572 } 573 574 void FrameLoaderClientImpl::didRunInsecureContent(SecurityOrigin* origin, const KURL& insecureURL) 575 { 576 if (m_webFrame->client()) 577 m_webFrame->client()->didRunInsecureContent(m_webFrame, WebSecurityOrigin(origin), insecureURL); 578 } 579 580 void FrameLoaderClientImpl::didDetectXSS(const KURL& insecureURL, bool didBlockEntirePage) 581 { 582 if (m_webFrame->client()) 583 m_webFrame->client()->didDetectXSS(m_webFrame, insecureURL, didBlockEntirePage); 584 } 585 586 void FrameLoaderClientImpl::didDispatchPingLoader(const KURL& url) 587 { 588 if (m_webFrame->client()) 589 m_webFrame->client()->didDispatchPingLoader(m_webFrame, url); 590 } 591 592 ResourceError FrameLoaderClientImpl::interruptedForPolicyChangeError( 593 const ResourceRequest& request) 594 { 595 return ResourceError(internalErrorDomain, PolicyChangeError, 596 request.url().string(), String()); 597 } 598 599 PassRefPtr<DocumentLoader> FrameLoaderClientImpl::createDocumentLoader( 600 const ResourceRequest& request, 601 const SubstituteData& data) 602 { 603 RefPtr<WebDataSourceImpl> ds = WebDataSourceImpl::create(request, data); 604 if (m_webFrame->client()) 605 m_webFrame->client()->didCreateDataSource(m_webFrame, ds.get()); 606 return ds.release(); 607 } 608 609 String FrameLoaderClientImpl::userAgent(const KURL& url) 610 { 611 WebString override = m_webFrame->client()->userAgentOverride(m_webFrame, WebURL(url)); 612 if (!override.isEmpty()) 613 return override; 614 615 return WebKit::Platform::current()->userAgent(url); 616 } 617 618 String FrameLoaderClientImpl::doNotTrackValue() 619 { 620 WebString doNotTrack = m_webFrame->client()->doNotTrackValue(m_webFrame); 621 if (!doNotTrack.isEmpty()) 622 return doNotTrack; 623 return String(); 624 } 625 626 // Called when the FrameLoader goes into a state in which a new page load 627 // will occur. 628 void FrameLoaderClientImpl::transitionToCommittedForNewPage() 629 { 630 m_webFrame->createFrameView(); 631 } 632 633 PassRefPtr<Frame> FrameLoaderClientImpl::createFrame( 634 const KURL& url, 635 const String& name, 636 HTMLFrameOwnerElement* ownerElement, 637 const String& referrer, 638 bool allowsScrolling, 639 int marginWidth, 640 int marginHeight) 641 { 642 FrameLoadRequest frameRequest(m_webFrame->frame()->document()->securityOrigin(), 643 ResourceRequest(url, referrer), name); 644 return m_webFrame->createChildFrame(frameRequest, ownerElement); 645 } 646 647 PassRefPtr<Widget> FrameLoaderClientImpl::createPlugin( 648 const IntSize& size, // FIXME: how do we use this? 649 HTMLPlugInElement* element, 650 const KURL& url, 651 const Vector<String>& paramNames, 652 const Vector<String>& paramValues, 653 const String& mimeType, 654 bool loadManually) 655 { 656 if (!m_webFrame->client()) 657 return 0; 658 659 WebPluginParams params; 660 params.url = url; 661 params.mimeType = mimeType; 662 params.attributeNames = paramNames; 663 params.attributeValues = paramValues; 664 params.loadManually = loadManually; 665 666 WebPlugin* webPlugin = m_webFrame->client()->createPlugin(m_webFrame, params); 667 if (!webPlugin) 668 return 0; 669 670 // The container takes ownership of the WebPlugin. 671 RefPtr<WebPluginContainerImpl> container = 672 WebPluginContainerImpl::create(element, webPlugin); 673 674 if (!webPlugin->initialize(container.get())) 675 return 0; 676 677 // The element might have been removed during plugin initialization! 678 if (!element->renderer()) 679 return 0; 680 681 return container; 682 } 683 684 PassRefPtr<Widget> FrameLoaderClientImpl::createJavaAppletWidget( 685 const IntSize& size, 686 HTMLAppletElement* element, 687 const KURL& /* baseURL */, 688 const Vector<String>& paramNames, 689 const Vector<String>& paramValues) 690 { 691 return createPlugin(size, element, KURL(), paramNames, paramValues, 692 "application/x-java-applet", false); 693 } 694 695 ObjectContentType FrameLoaderClientImpl::objectContentType( 696 const KURL& url, 697 const String& explicitMimeType, 698 bool shouldPreferPlugInsForImages) 699 { 700 // This code is based on Apple's implementation from 701 // WebCoreSupport/WebFrameBridge.mm. 702 703 String mimeType = explicitMimeType; 704 if (mimeType.isEmpty()) { 705 // Try to guess the MIME type based off the extension. 706 String filename = url.lastPathComponent(); 707 int extensionPos = filename.reverseFind('.'); 708 if (extensionPos >= 0) { 709 String extension = filename.substring(extensionPos + 1); 710 mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension); 711 if (mimeType.isEmpty()) { 712 // If there's no mimetype registered for the extension, check to see 713 // if a plugin can handle the extension. 714 mimeType = getPluginMimeTypeFromExtension(extension); 715 } 716 } 717 718 if (mimeType.isEmpty()) 719 return ObjectContentFrame; 720 } 721 722 // If Chrome is started with the --disable-plugins switch, pluginData is 0. 723 PluginData* pluginData = m_webFrame->frame()->page()->pluginData(); 724 bool plugInSupportsMIMEType = pluginData && pluginData->supportsMimeType(mimeType); 725 726 if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType)) 727 return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? ObjectContentNetscapePlugin : ObjectContentImage; 728 729 if (plugInSupportsMIMEType) 730 return ObjectContentNetscapePlugin; 731 732 if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType)) 733 return ObjectContentFrame; 734 735 return ObjectContentNone; 736 } 737 738 PassOwnPtr<WebPluginLoadObserver> FrameLoaderClientImpl::pluginLoadObserver() 739 { 740 WebDataSourceImpl* ds = WebDataSourceImpl::fromDocumentLoader( 741 m_webFrame->frame()->loader()->activeDocumentLoader()); 742 if (!ds) { 743 // We can arrive here if a popstate event handler detaches this frame. 744 // FIXME: Remove this code once http://webkit.org/b/36202 is fixed. 745 ASSERT(!m_webFrame->frame()->page()); 746 return nullptr; 747 } 748 return ds->releasePluginLoadObserver(); 749 } 750 751 WebCookieJar* FrameLoaderClientImpl::cookieJar() const 752 { 753 if (!m_webFrame->client()) 754 return 0; 755 return m_webFrame->client()->cookieJar(m_webFrame); 756 } 757 758 bool FrameLoaderClientImpl::willCheckAndDispatchMessageEvent( 759 SecurityOrigin* target, MessageEvent* event) const 760 { 761 if (!m_webFrame->client()) 762 return false; 763 764 WebFrame* source = 0; 765 if (event && event->source() && event->source()->document()) 766 source = WebFrameImpl::fromFrame(event->source()->document()->frame()); 767 return m_webFrame->client()->willCheckAndDispatchMessageEvent( 768 source, m_webFrame, WebSecurityOrigin(target), WebDOMMessageEvent(event)); 769 } 770 771 void FrameLoaderClientImpl::didChangeName(const String& name) 772 { 773 if (!m_webFrame->client()) 774 return; 775 m_webFrame->client()->didChangeName(m_webFrame, name); 776 } 777 778 void FrameLoaderClientImpl::dispatchWillOpenSocketStream(SocketStreamHandle* handle) 779 { 780 m_webFrame->client()->willOpenSocketStream(SocketStreamHandleInternal::toWebSocketStreamHandle(handle)); 781 } 782 783 void FrameLoaderClientImpl::dispatchWillStartUsingPeerConnectionHandler(RTCPeerConnectionHandler* handler) 784 { 785 m_webFrame->client()->willStartUsingPeerConnectionHandler(webFrame(), RTCPeerConnectionHandler::toWebRTCPeerConnectionHandler(handler)); 786 } 787 788 void FrameLoaderClientImpl::didRequestAutocomplete(PassRefPtr<FormState> formState) 789 { 790 if (m_webFrame->viewImpl() && m_webFrame->viewImpl()->autofillClient()) 791 m_webFrame->viewImpl()->autofillClient()->didRequestAutocomplete(m_webFrame, WebFormElement(formState->form())); 792 } 793 794 bool FrameLoaderClientImpl::allowWebGL(bool enabledPerSettings) 795 { 796 if (m_webFrame->client()) 797 return m_webFrame->client()->allowWebGL(m_webFrame, enabledPerSettings); 798 799 return enabledPerSettings; 800 } 801 802 void FrameLoaderClientImpl::didLoseWebGLContext(int arbRobustnessContextLostReason) 803 { 804 if (m_webFrame->client()) 805 m_webFrame->client()->didLoseWebGLContext(m_webFrame, arbRobustnessContextLostReason); 806 } 807 808 void FrameLoaderClientImpl::dispatchWillInsertBody() 809 { 810 if (m_webFrame->client()) 811 m_webFrame->client()->willInsertBody(m_webFrame); 812 } 813 814 } // namespace WebKit 815