Home | History | Annotate | Download | only in web
      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