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 "web/FrameLoaderClientImpl.h"
     34 
     35 #include "bindings/core/v8/ScriptController.h"
     36 #include "core/HTMLNames.h"
     37 #include "core/dom/Document.h"
     38 #include "core/dom/Fullscreen.h"
     39 #include "core/events/MessageEvent.h"
     40 #include "core/events/MouseEvent.h"
     41 #include "core/frame/FrameView.h"
     42 #include "core/frame/Settings.h"
     43 #include "core/html/HTMLAppletElement.h"
     44 #include "core/loader/DocumentLoader.h"
     45 #include "core/loader/FrameLoadRequest.h"
     46 #include "core/loader/FrameLoader.h"
     47 #include "core/loader/HistoryItem.h"
     48 #include "core/page/Chrome.h"
     49 #include "core/page/EventHandler.h"
     50 #include "core/page/Page.h"
     51 #include "core/page/WindowFeatures.h"
     52 #include "core/rendering/HitTestResult.h"
     53 #include "modules/device_light/DeviceLightController.h"
     54 #include "modules/device_orientation/DeviceMotionController.h"
     55 #include "modules/device_orientation/DeviceOrientationController.h"
     56 #include "modules/gamepad/NavigatorGamepad.h"
     57 #include "modules/serviceworkers/NavigatorServiceWorker.h"
     58 #include "platform/MIMETypeRegistry.h"
     59 #include "platform/RuntimeEnabledFeatures.h"
     60 #include "platform/UserGestureIndicator.h"
     61 #include "platform/exported/WrappedResourceRequest.h"
     62 #include "platform/exported/WrappedResourceResponse.h"
     63 #include "platform/network/HTTPParsers.h"
     64 #include "platform/network/SocketStreamHandleInternal.h"
     65 #include "platform/plugins/PluginData.h"
     66 #include "public/platform/Platform.h"
     67 #include "public/platform/WebApplicationCacheHost.h"
     68 #include "public/platform/WebMimeRegistry.h"
     69 #include "public/platform/WebRTCPeerConnectionHandler.h"
     70 #include "public/platform/WebServiceWorkerProvider.h"
     71 #include "public/platform/WebServiceWorkerProviderClient.h"
     72 #include "public/platform/WebSocketStreamHandle.h"
     73 #include "public/platform/WebURL.h"
     74 #include "public/platform/WebURLError.h"
     75 #include "public/platform/WebVector.h"
     76 #include "public/web/WebAutofillClient.h"
     77 #include "public/web/WebCachedURLRequest.h"
     78 #include "public/web/WebDOMEvent.h"
     79 #include "public/web/WebDocument.h"
     80 #include "public/web/WebFormElement.h"
     81 #include "public/web/WebFrameClient.h"
     82 #include "public/web/WebNode.h"
     83 #include "public/web/WebPermissionClient.h"
     84 #include "public/web/WebPlugin.h"
     85 #include "public/web/WebPluginParams.h"
     86 #include "public/web/WebSecurityOrigin.h"
     87 #include "public/web/WebViewClient.h"
     88 #include "web/SharedWorkerRepositoryClientImpl.h"
     89 #include "web/WebDataSourceImpl.h"
     90 #include "web/WebDevToolsAgentPrivate.h"
     91 #include "web/WebLocalFrameImpl.h"
     92 #include "web/WebPluginContainerImpl.h"
     93 #include "web/WebPluginLoadObserver.h"
     94 #include "web/WebViewImpl.h"
     95 #include "wtf/StringExtras.h"
     96 #include "wtf/text/CString.h"
     97 #include "wtf/text/WTFString.h"
     98 #include <v8.h>
     99 
    100 namespace blink {
    101 
    102 FrameLoaderClientImpl::FrameLoaderClientImpl(WebLocalFrameImpl* frame)
    103     : m_webFrame(frame)
    104 {
    105 }
    106 
    107 FrameLoaderClientImpl::~FrameLoaderClientImpl()
    108 {
    109 }
    110 
    111 void FrameLoaderClientImpl::dispatchDidClearWindowObjectInMainWorld()
    112 {
    113     if (m_webFrame->client()) {
    114         m_webFrame->client()->didClearWindowObject(m_webFrame);
    115         Document* document = m_webFrame->frame()->document();
    116         if (document) {
    117             DeviceMotionController::from(*document);
    118             DeviceOrientationController::from(*document);
    119             if (RuntimeEnabledFeatures::deviceLightEnabled())
    120                 DeviceLightController::from(*document);
    121             if (RuntimeEnabledFeatures::gamepadEnabled())
    122                 NavigatorGamepad::from(*document);
    123             if (RuntimeEnabledFeatures::serviceWorkerEnabled())
    124                 NavigatorServiceWorker::from(*document);
    125         }
    126     }
    127 }
    128 
    129 void FrameLoaderClientImpl::documentElementAvailable()
    130 {
    131     if (m_webFrame->client())
    132         m_webFrame->client()->didCreateDocumentElement(m_webFrame);
    133 }
    134 
    135 void FrameLoaderClientImpl::didCreateScriptContext(v8::Handle<v8::Context> context, int extensionGroup, int worldId)
    136 {
    137     WebViewImpl* webview = m_webFrame->viewImpl();
    138     if (webview->devToolsAgentPrivate())
    139         webview->devToolsAgentPrivate()->didCreateScriptContext(m_webFrame, worldId);
    140     if (m_webFrame->client())
    141         m_webFrame->client()->didCreateScriptContext(m_webFrame, context, extensionGroup, worldId);
    142 }
    143 
    144 void FrameLoaderClientImpl::willReleaseScriptContext(v8::Handle<v8::Context> context, int worldId)
    145 {
    146     if (m_webFrame->client())
    147         m_webFrame->client()->willReleaseScriptContext(m_webFrame, context, worldId);
    148 }
    149 
    150 bool FrameLoaderClientImpl::allowScriptExtension(const String& extensionName,
    151                                                  int extensionGroup,
    152                                                  int worldId)
    153 {
    154     if (m_webFrame->permissionClient())
    155         return m_webFrame->permissionClient()->allowScriptExtension(extensionName, extensionGroup, worldId);
    156 
    157     return true;
    158 }
    159 
    160 void FrameLoaderClientImpl::didChangeScrollOffset()
    161 {
    162     if (m_webFrame->client())
    163         m_webFrame->client()->didChangeScrollOffset(m_webFrame);
    164 }
    165 
    166 void FrameLoaderClientImpl::didUpdateCurrentHistoryItem()
    167 {
    168     if (m_webFrame->client())
    169         m_webFrame->client()->didUpdateCurrentHistoryItem(m_webFrame);
    170 }
    171 
    172 void FrameLoaderClientImpl::didRemoveAllPendingStylesheet()
    173 {
    174     WebViewImpl* webview = m_webFrame->viewImpl();
    175     if (webview)
    176         webview->didRemoveAllPendingStylesheet(m_webFrame);
    177 }
    178 
    179 bool FrameLoaderClientImpl::allowScript(bool enabledPerSettings)
    180 {
    181     if (m_webFrame->permissionClient())
    182         return m_webFrame->permissionClient()->allowScript(enabledPerSettings);
    183 
    184     return enabledPerSettings;
    185 }
    186 
    187 bool FrameLoaderClientImpl::allowScriptFromSource(bool enabledPerSettings, const KURL& scriptURL)
    188 {
    189     if (m_webFrame->permissionClient())
    190         return m_webFrame->permissionClient()->allowScriptFromSource(enabledPerSettings, scriptURL);
    191 
    192     return enabledPerSettings;
    193 }
    194 
    195 bool FrameLoaderClientImpl::allowPlugins(bool enabledPerSettings)
    196 {
    197     if (m_webFrame->permissionClient())
    198         return m_webFrame->permissionClient()->allowPlugins(enabledPerSettings);
    199 
    200     return enabledPerSettings;
    201 }
    202 
    203 bool FrameLoaderClientImpl::allowImage(bool enabledPerSettings, const KURL& imageURL)
    204 {
    205     if (m_webFrame->permissionClient())
    206         return m_webFrame->permissionClient()->allowImage(enabledPerSettings, imageURL);
    207 
    208     return enabledPerSettings;
    209 }
    210 
    211 bool FrameLoaderClientImpl::allowMedia(const KURL& mediaURL)
    212 {
    213     if (m_webFrame->permissionClient())
    214         return m_webFrame->permissionClient()->allowMedia(mediaURL);
    215 
    216     return true;
    217 }
    218 
    219 bool FrameLoaderClientImpl::allowDisplayingInsecureContent(bool enabledPerSettings, SecurityOrigin* context, const KURL& url)
    220 {
    221     if (m_webFrame->permissionClient())
    222         return m_webFrame->permissionClient()->allowDisplayingInsecureContent(enabledPerSettings, WebSecurityOrigin(context), WebURL(url));
    223 
    224     return enabledPerSettings;
    225 }
    226 
    227 bool FrameLoaderClientImpl::allowRunningInsecureContent(bool enabledPerSettings, SecurityOrigin* context, const KURL& url)
    228 {
    229     if (m_webFrame->permissionClient())
    230         return m_webFrame->permissionClient()->allowRunningInsecureContent(enabledPerSettings, WebSecurityOrigin(context), WebURL(url));
    231 
    232     return enabledPerSettings;
    233 }
    234 
    235 void FrameLoaderClientImpl::didNotAllowScript()
    236 {
    237     if (m_webFrame->permissionClient())
    238         m_webFrame->permissionClient()->didNotAllowScript();
    239 }
    240 
    241 void FrameLoaderClientImpl::didNotAllowPlugins()
    242 {
    243     if (m_webFrame->permissionClient())
    244         m_webFrame->permissionClient()->didNotAllowPlugins();
    245 
    246 }
    247 
    248 bool FrameLoaderClientImpl::hasWebView() const
    249 {
    250     return m_webFrame->viewImpl();
    251 }
    252 
    253 Frame* FrameLoaderClientImpl::opener() const
    254 {
    255     return toCoreFrame(m_webFrame->opener());
    256 }
    257 
    258 void FrameLoaderClientImpl::setOpener(Frame* opener)
    259 {
    260     m_webFrame->setOpener(WebFrame::fromFrame(opener));
    261 }
    262 
    263 Frame* FrameLoaderClientImpl::parent() const
    264 {
    265     return toCoreFrame(m_webFrame->parent());
    266 }
    267 
    268 Frame* FrameLoaderClientImpl::top() const
    269 {
    270     return toCoreFrame(m_webFrame->top());
    271 }
    272 
    273 Frame* FrameLoaderClientImpl::previousSibling() const
    274 {
    275     return toCoreFrame(m_webFrame->previousSibling());
    276 }
    277 
    278 Frame* FrameLoaderClientImpl::nextSibling() const
    279 {
    280     return toCoreFrame(m_webFrame->nextSibling());
    281 }
    282 
    283 Frame* FrameLoaderClientImpl::firstChild() const
    284 {
    285     return toCoreFrame(m_webFrame->firstChild());
    286 }
    287 
    288 Frame* FrameLoaderClientImpl::lastChild() const
    289 {
    290     return toCoreFrame(m_webFrame->lastChild());
    291 }
    292 
    293 void FrameLoaderClientImpl::detachedFromParent()
    294 {
    295     // Alert the client that the frame is being detached. This is the last
    296     // chance we have to communicate with the client.
    297     RefPtrWillBeRawPtr<WebLocalFrameImpl> protector(m_webFrame);
    298 
    299     WebFrameClient* client = m_webFrame->client();
    300     if (!client)
    301         return;
    302 
    303     m_webFrame->willDetachParent();
    304 
    305     // Signal that no further communication with WebFrameClient should take
    306     // place at this point since we are no longer associated with the Page.
    307     m_webFrame->setClient(0);
    308 
    309     client->frameDetached(m_webFrame);
    310     // Clear our reference to LocalFrame at the very end, in case the client
    311     // refers to it.
    312     m_webFrame->setCoreFrame(nullptr);
    313 }
    314 
    315 void FrameLoaderClientImpl::dispatchWillSendRequest(
    316     DocumentLoader* loader, unsigned long identifier, ResourceRequest& request,
    317     const ResourceResponse& redirectResponse)
    318 {
    319     // Give the WebFrameClient a crack at the request.
    320     if (m_webFrame->client()) {
    321         WrappedResourceRequest webreq(request);
    322         WrappedResourceResponse webresp(redirectResponse);
    323         m_webFrame->client()->willSendRequest(
    324             m_webFrame, identifier, webreq, webresp);
    325     }
    326 }
    327 
    328 void FrameLoaderClientImpl::dispatchDidReceiveResponse(DocumentLoader* loader,
    329                                                        unsigned long identifier,
    330                                                        const ResourceResponse& response)
    331 {
    332     if (m_webFrame->client()) {
    333         WrappedResourceResponse webresp(response);
    334         m_webFrame->client()->didReceiveResponse(m_webFrame, identifier, webresp);
    335     }
    336 }
    337 
    338 void FrameLoaderClientImpl::dispatchDidChangeResourcePriority(unsigned long identifier, ResourceLoadPriority priority, int intraPriorityValue)
    339 {
    340     if (m_webFrame->client())
    341         m_webFrame->client()->didChangeResourcePriority(m_webFrame, identifier, static_cast<WebURLRequest::Priority>(priority), intraPriorityValue);
    342 }
    343 
    344 // Called when a particular resource load completes
    345 void FrameLoaderClientImpl::dispatchDidFinishLoading(DocumentLoader* loader,
    346                                                     unsigned long identifier)
    347 {
    348     if (m_webFrame->client())
    349         m_webFrame->client()->didFinishResourceLoad(m_webFrame, identifier);
    350 }
    351 
    352 void FrameLoaderClientImpl::dispatchDidFinishDocumentLoad()
    353 {
    354     if (m_webFrame->client())
    355         m_webFrame->client()->didFinishDocumentLoad(m_webFrame);
    356 }
    357 
    358 void FrameLoaderClientImpl::dispatchDidLoadResourceFromMemoryCache(const ResourceRequest& request, const ResourceResponse& response)
    359 {
    360     if (m_webFrame->client())
    361         m_webFrame->client()->didLoadResourceFromMemoryCache(m_webFrame, WrappedResourceRequest(request), WrappedResourceResponse(response));
    362 }
    363 
    364 void FrameLoaderClientImpl::dispatchDidHandleOnloadEvents()
    365 {
    366     if (m_webFrame->client())
    367         m_webFrame->client()->didHandleOnloadEvents(m_webFrame);
    368 }
    369 
    370 void FrameLoaderClientImpl::dispatchDidReceiveServerRedirectForProvisionalLoad()
    371 {
    372     if (m_webFrame->client())
    373         m_webFrame->client()->didReceiveServerRedirectForProvisionalLoad(m_webFrame);
    374 }
    375 
    376 void FrameLoaderClientImpl::dispatchDidNavigateWithinPage(HistoryItem* item, HistoryCommitType commitType)
    377 {
    378     bool shouldCreateHistoryEntry = commitType == StandardCommit;
    379     m_webFrame->viewImpl()->didCommitLoad(shouldCreateHistoryEntry, true);
    380     if (m_webFrame->client())
    381         m_webFrame->client()->didNavigateWithinPage(m_webFrame, WebHistoryItem(item), static_cast<WebHistoryCommitType>(commitType));
    382 }
    383 
    384 void FrameLoaderClientImpl::dispatchWillClose()
    385 {
    386     if (m_webFrame->client())
    387         m_webFrame->client()->willClose(m_webFrame);
    388 }
    389 
    390 void FrameLoaderClientImpl::dispatchDidStartProvisionalLoad(bool isTransitionNavigation)
    391 {
    392     if (m_webFrame->client())
    393         m_webFrame->client()->didStartProvisionalLoad(m_webFrame, isTransitionNavigation);
    394 }
    395 
    396 void FrameLoaderClientImpl::dispatchDidReceiveTitle(const String& title)
    397 {
    398     if (m_webFrame->client())
    399         m_webFrame->client()->didReceiveTitle(m_webFrame, title, WebTextDirectionLeftToRight);
    400 }
    401 
    402 void FrameLoaderClientImpl::dispatchDidChangeIcons(IconType type)
    403 {
    404     if (m_webFrame->client())
    405         m_webFrame->client()->didChangeIcon(m_webFrame, static_cast<WebIconURL::Type>(type));
    406 }
    407 
    408 void FrameLoaderClientImpl::dispatchDidCommitLoad(LocalFrame* frame, HistoryItem* item, HistoryCommitType commitType)
    409 {
    410     m_webFrame->viewImpl()->didCommitLoad(commitType == StandardCommit, false);
    411     if (m_webFrame->client())
    412         m_webFrame->client()->didCommitProvisionalLoad(m_webFrame, WebHistoryItem(item), static_cast<WebHistoryCommitType>(commitType));
    413 }
    414 
    415 void FrameLoaderClientImpl::dispatchDidFailProvisionalLoad(
    416     const ResourceError& error)
    417 {
    418     OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver(m_webFrame->frame()->loader().provisionalDocumentLoader());
    419     m_webFrame->didFail(error, true);
    420     if (observer)
    421         observer->didFailLoading(error);
    422 }
    423 
    424 void FrameLoaderClientImpl::dispatchDidFailLoad(const ResourceError& error)
    425 {
    426     OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver(m_webFrame->frame()->loader().documentLoader());
    427     m_webFrame->didFail(error, false);
    428     if (observer)
    429         observer->didFailLoading(error);
    430 
    431     // Don't clear the redirect chain, this will happen in the middle of client
    432     // redirects, and we need the context. The chain will be cleared when the
    433     // provisional load succeeds or fails, not the "real" one.
    434 }
    435 
    436 void FrameLoaderClientImpl::dispatchDidFinishLoad()
    437 {
    438     OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver(m_webFrame->frame()->loader().documentLoader());
    439 
    440     if (m_webFrame->client())
    441         m_webFrame->client()->didFinishLoad(m_webFrame);
    442 
    443     if (observer)
    444         observer->didFinishLoading();
    445 
    446     // Don't clear the redirect chain, this will happen in the middle of client
    447     // redirects, and we need the context. The chain will be cleared when the
    448     // provisional load succeeds or fails, not the "real" one.
    449 }
    450 
    451 void FrameLoaderClientImpl::dispatchDidFirstVisuallyNonEmptyLayout()
    452 {
    453     if (m_webFrame->client())
    454         m_webFrame->client()->didFirstVisuallyNonEmptyLayout(m_webFrame);
    455 }
    456 
    457 void FrameLoaderClientImpl::dispatchDidChangeThemeColor()
    458 {
    459     if (m_webFrame->client())
    460         m_webFrame->client()->didChangeThemeColor();
    461 }
    462 
    463 NavigationPolicy FrameLoaderClientImpl::decidePolicyForNavigation(const ResourceRequest& request, DocumentLoader* loader, NavigationPolicy policy, bool isTransitionNavigation)
    464 {
    465     if (!m_webFrame->client())
    466         return NavigationPolicyIgnore;
    467     WebDataSourceImpl* ds = WebDataSourceImpl::fromDocumentLoader(loader);
    468 
    469     WrappedResourceRequest wrappedResourceRequest(request);
    470     WebFrameClient::NavigationPolicyInfo navigationInfo(wrappedResourceRequest);
    471     navigationInfo.frame = m_webFrame;
    472     navigationInfo.extraData = ds->extraData();
    473     navigationInfo.navigationType = ds->navigationType();
    474     navigationInfo.defaultPolicy = static_cast<WebNavigationPolicy>(policy);
    475     navigationInfo.isRedirect = ds->isRedirect();
    476     navigationInfo.isTransitionNavigation = isTransitionNavigation;
    477 
    478     WebNavigationPolicy webPolicy = m_webFrame->client()->decidePolicyForNavigation(navigationInfo);
    479     return static_cast<NavigationPolicy>(webPolicy);
    480 }
    481 
    482 void FrameLoaderClientImpl::dispatchAddNavigationTransitionData(const String& allowedDestinationOrigin, const String& selector, const String& markup)
    483 {
    484     if (m_webFrame->client())
    485         m_webFrame->client()->addNavigationTransitionData(allowedDestinationOrigin, selector, markup);
    486 }
    487 
    488 void FrameLoaderClientImpl::dispatchWillRequestResource(FetchRequest* request)
    489 {
    490     if (m_webFrame->client()) {
    491         WebCachedURLRequest urlRequest(request);
    492         m_webFrame->client()->willRequestResource(m_webFrame, urlRequest);
    493     }
    494 }
    495 
    496 void FrameLoaderClientImpl::dispatchWillSendSubmitEvent(HTMLFormElement* form)
    497 {
    498     if (m_webFrame->client())
    499         m_webFrame->client()->willSendSubmitEvent(m_webFrame, WebFormElement(form));
    500 }
    501 
    502 void FrameLoaderClientImpl::dispatchWillSubmitForm(HTMLFormElement* form)
    503 {
    504     if (m_webFrame->client())
    505         m_webFrame->client()->willSubmitForm(m_webFrame, WebFormElement(form));
    506 }
    507 
    508 void FrameLoaderClientImpl::didStartLoading(LoadStartType loadStartType)
    509 {
    510     if (m_webFrame->client())
    511         m_webFrame->client()->didStartLoading(loadStartType == NavigationToDifferentDocument);
    512 }
    513 
    514 void FrameLoaderClientImpl::progressEstimateChanged(double progressEstimate)
    515 {
    516     if (m_webFrame->client())
    517         m_webFrame->client()->didChangeLoadProgress(progressEstimate);
    518 }
    519 
    520 void FrameLoaderClientImpl::didStopLoading()
    521 {
    522     if (m_webFrame->client())
    523         m_webFrame->client()->didStopLoading();
    524 }
    525 
    526 void FrameLoaderClientImpl::loadURLExternally(const ResourceRequest& request, NavigationPolicy policy, const String& suggestedName)
    527 {
    528     if (m_webFrame->client()) {
    529         ASSERT(m_webFrame->frame()->document());
    530         Fullscreen::fullyExitFullscreen(*m_webFrame->frame()->document());
    531         WrappedResourceRequest webreq(request);
    532         m_webFrame->client()->loadURLExternally(
    533             m_webFrame, webreq, static_cast<WebNavigationPolicy>(policy), suggestedName);
    534     }
    535 }
    536 
    537 bool FrameLoaderClientImpl::navigateBackForward(int offset) const
    538 {
    539     WebViewImpl* webview = m_webFrame->viewImpl();
    540     if (!webview->client())
    541         return false;
    542 
    543     ASSERT(offset);
    544     offset = std::min(offset, webview->client()->historyForwardListCount());
    545     offset = std::max(offset, -webview->client()->historyBackListCount());
    546     if (!offset)
    547         return false;
    548     webview->client()->navigateBackForwardSoon(offset);
    549     return true;
    550 }
    551 
    552 void FrameLoaderClientImpl::didAccessInitialDocument()
    553 {
    554     if (m_webFrame->client())
    555         m_webFrame->client()->didAccessInitialDocument(m_webFrame);
    556 }
    557 
    558 void FrameLoaderClientImpl::didDisplayInsecureContent()
    559 {
    560     if (m_webFrame->client())
    561         m_webFrame->client()->didDisplayInsecureContent(m_webFrame);
    562 }
    563 
    564 void FrameLoaderClientImpl::didRunInsecureContent(SecurityOrigin* origin, const KURL& insecureURL)
    565 {
    566     if (m_webFrame->client())
    567         m_webFrame->client()->didRunInsecureContent(m_webFrame, WebSecurityOrigin(origin), insecureURL);
    568 }
    569 
    570 void FrameLoaderClientImpl::didDetectXSS(const KURL& insecureURL, bool didBlockEntirePage)
    571 {
    572     if (m_webFrame->client())
    573         m_webFrame->client()->didDetectXSS(m_webFrame, insecureURL, didBlockEntirePage);
    574 }
    575 
    576 void FrameLoaderClientImpl::didDispatchPingLoader(const KURL& url)
    577 {
    578     if (m_webFrame->client())
    579         m_webFrame->client()->didDispatchPingLoader(m_webFrame, url);
    580 }
    581 
    582 void FrameLoaderClientImpl::selectorMatchChanged(const Vector<String>& addedSelectors, const Vector<String>& removedSelectors)
    583 {
    584     if (WebFrameClient* client = m_webFrame->client())
    585         client->didMatchCSS(m_webFrame, WebVector<WebString>(addedSelectors), WebVector<WebString>(removedSelectors));
    586 }
    587 
    588 PassRefPtr<DocumentLoader> FrameLoaderClientImpl::createDocumentLoader(LocalFrame* frame, const ResourceRequest& request, const SubstituteData& data)
    589 {
    590     RefPtr<WebDataSourceImpl> ds = WebDataSourceImpl::create(frame, request, data);
    591     if (m_webFrame->client())
    592         m_webFrame->client()->didCreateDataSource(m_webFrame, ds.get());
    593     return ds.release();
    594 }
    595 
    596 String FrameLoaderClientImpl::userAgent(const KURL& url)
    597 {
    598     WebString override = m_webFrame->client()->userAgentOverride(m_webFrame, WebURL(url));
    599     if (!override.isEmpty())
    600         return override;
    601 
    602     return Platform::current()->userAgent();
    603 }
    604 
    605 String FrameLoaderClientImpl::doNotTrackValue()
    606 {
    607     WebString doNotTrack = m_webFrame->client()->doNotTrackValue(m_webFrame);
    608     if (!doNotTrack.isEmpty())
    609         return doNotTrack;
    610     return String();
    611 }
    612 
    613 // Called when the FrameLoader goes into a state in which a new page load
    614 // will occur.
    615 void FrameLoaderClientImpl::transitionToCommittedForNewPage()
    616 {
    617     m_webFrame->createFrameView();
    618 }
    619 
    620 PassRefPtrWillBeRawPtr<LocalFrame> FrameLoaderClientImpl::createFrame(
    621     const KURL& url,
    622     const AtomicString& name,
    623     const Referrer& referrer,
    624     HTMLFrameOwnerElement* ownerElement)
    625 {
    626     FrameLoadRequest frameRequest(m_webFrame->frame()->document(),
    627         ResourceRequest(url, referrer), name);
    628     return m_webFrame->createChildFrame(frameRequest, ownerElement);
    629 }
    630 
    631 bool FrameLoaderClientImpl::canCreatePluginWithoutRenderer(const String& mimeType) const
    632 {
    633     if (!m_webFrame->client())
    634         return false;
    635 
    636     return m_webFrame->client()->canCreatePluginWithoutRenderer(mimeType);
    637 }
    638 
    639 PassRefPtr<Widget> FrameLoaderClientImpl::createPlugin(
    640     HTMLPlugInElement* element,
    641     const KURL& url,
    642     const Vector<String>& paramNames,
    643     const Vector<String>& paramValues,
    644     const String& mimeType,
    645     bool loadManually,
    646     DetachedPluginPolicy policy)
    647 {
    648     if (!m_webFrame->client())
    649         return nullptr;
    650 
    651     WebPluginParams params;
    652     params.url = url;
    653     params.mimeType = mimeType;
    654     params.attributeNames = paramNames;
    655     params.attributeValues = paramValues;
    656     params.loadManually = loadManually;
    657 
    658     WebPlugin* webPlugin = m_webFrame->client()->createPlugin(m_webFrame, params);
    659     if (!webPlugin)
    660         return nullptr;
    661 
    662     // The container takes ownership of the WebPlugin.
    663     RefPtr<WebPluginContainerImpl> container =
    664         WebPluginContainerImpl::create(element, webPlugin);
    665 
    666     if (!webPlugin->initialize(container.get()))
    667         return nullptr;
    668 
    669     if (policy != AllowDetachedPlugin && !element->renderer())
    670         return nullptr;
    671 
    672     return container;
    673 }
    674 
    675 PassRefPtr<Widget> FrameLoaderClientImpl::createJavaAppletWidget(
    676     HTMLAppletElement* element,
    677     const KURL& /* baseURL */,
    678     const Vector<String>& paramNames,
    679     const Vector<String>& paramValues)
    680 {
    681     return createPlugin(element, KURL(), paramNames, paramValues,
    682         "application/x-java-applet", false, FailOnDetachedPlugin);
    683 }
    684 
    685 ObjectContentType FrameLoaderClientImpl::objectContentType(
    686     const KURL& url,
    687     const String& explicitMimeType,
    688     bool shouldPreferPlugInsForImages)
    689 {
    690     // This code is based on Apple's implementation from
    691     // WebCoreSupport/WebFrameBridge.mm.
    692 
    693     String mimeType = explicitMimeType;
    694     if (mimeType.isEmpty()) {
    695         // Try to guess the MIME type based off the extension.
    696         String filename = url.lastPathComponent();
    697         int extensionPos = filename.reverseFind('.');
    698         if (extensionPos >= 0) {
    699             String extension = filename.substring(extensionPos + 1);
    700             mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
    701             if (mimeType.isEmpty()) {
    702                 // If there's no mimetype registered for the extension, check to see
    703                 // if a plugin can handle the extension.
    704                 mimeType = getPluginMimeTypeFromExtension(extension);
    705             }
    706         }
    707 
    708         if (mimeType.isEmpty())
    709             return ObjectContentFrame;
    710     }
    711 
    712     // If Chrome is started with the --disable-plugins switch, pluginData is 0.
    713     PluginData* pluginData = m_webFrame->frame()->page()->pluginData();
    714     bool plugInSupportsMIMEType = pluginData && pluginData->supportsMimeType(mimeType);
    715 
    716     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
    717         return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? ObjectContentNetscapePlugin : ObjectContentImage;
    718 
    719     if (plugInSupportsMIMEType)
    720         return ObjectContentNetscapePlugin;
    721 
    722     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
    723         return ObjectContentFrame;
    724 
    725     return ObjectContentNone;
    726 }
    727 
    728 PassOwnPtr<WebPluginLoadObserver> FrameLoaderClientImpl::pluginLoadObserver(DocumentLoader* loader)
    729 {
    730     return WebDataSourceImpl::fromDocumentLoader(loader)->releasePluginLoadObserver();
    731 }
    732 
    733 WebCookieJar* FrameLoaderClientImpl::cookieJar() const
    734 {
    735     if (!m_webFrame->client())
    736         return 0;
    737     return m_webFrame->client()->cookieJar(m_webFrame);
    738 }
    739 
    740 bool FrameLoaderClientImpl::willCheckAndDispatchMessageEvent(
    741     SecurityOrigin* target, MessageEvent* event, LocalFrame* sourceFrame) const
    742 {
    743     if (!m_webFrame->client())
    744         return false;
    745     return m_webFrame->client()->willCheckAndDispatchMessageEvent(
    746         WebLocalFrameImpl::fromFrame(sourceFrame), m_webFrame, WebSecurityOrigin(target), WebDOMMessageEvent(event));
    747 }
    748 
    749 void FrameLoaderClientImpl::didChangeName(const String& name)
    750 {
    751     if (!m_webFrame->client())
    752         return;
    753     m_webFrame->client()->didChangeName(m_webFrame, name);
    754 }
    755 
    756 void FrameLoaderClientImpl::dispatchWillOpenSocketStream(SocketStreamHandle* handle)
    757 {
    758     m_webFrame->client()->willOpenSocketStream(SocketStreamHandleInternal::toWebSocketStreamHandle(handle));
    759 }
    760 
    761 void FrameLoaderClientImpl::dispatchWillOpenWebSocket(WebSocketHandle* handle)
    762 {
    763     m_webFrame->client()->willOpenWebSocket(handle);
    764 }
    765 
    766 void FrameLoaderClientImpl::dispatchWillStartUsingPeerConnectionHandler(WebRTCPeerConnectionHandler* handler)
    767 {
    768     m_webFrame->client()->willStartUsingPeerConnectionHandler(webFrame(), handler);
    769 }
    770 
    771 void FrameLoaderClientImpl::didRequestAutocomplete(HTMLFormElement* form)
    772 {
    773     if (m_webFrame->viewImpl() && m_webFrame->viewImpl()->autofillClient())
    774         m_webFrame->viewImpl()->autofillClient()->didRequestAutocomplete(WebFormElement(form));
    775 }
    776 
    777 bool FrameLoaderClientImpl::allowWebGL(bool enabledPerSettings)
    778 {
    779     if (m_webFrame->client())
    780         return m_webFrame->client()->allowWebGL(m_webFrame, enabledPerSettings);
    781 
    782     return enabledPerSettings;
    783 }
    784 
    785 void FrameLoaderClientImpl::didLoseWebGLContext(int arbRobustnessContextLostReason)
    786 {
    787     if (m_webFrame->client())
    788         m_webFrame->client()->didLoseWebGLContext(m_webFrame, arbRobustnessContextLostReason);
    789 }
    790 
    791 void FrameLoaderClientImpl::dispatchWillInsertBody()
    792 {
    793     if (m_webFrame->client())
    794         m_webFrame->client()->willInsertBody(m_webFrame);
    795 
    796     if (m_webFrame->viewImpl())
    797         m_webFrame->viewImpl()->willInsertBody(m_webFrame);
    798 }
    799 
    800 PassOwnPtr<WebServiceWorkerProvider> FrameLoaderClientImpl::createServiceWorkerProvider()
    801 {
    802     if (!m_webFrame->client())
    803         return nullptr;
    804     return adoptPtr(m_webFrame->client()->createServiceWorkerProvider(m_webFrame));
    805 }
    806 
    807 bool FrameLoaderClientImpl::isControlledByServiceWorker()
    808 {
    809     return m_webFrame->client() && m_webFrame->client()->isControlledByServiceWorker();
    810 }
    811 
    812 SharedWorkerRepositoryClient* FrameLoaderClientImpl::sharedWorkerRepositoryClient()
    813 {
    814     return m_webFrame->sharedWorkerRepositoryClient();
    815 }
    816 
    817 PassOwnPtr<WebApplicationCacheHost> FrameLoaderClientImpl::createApplicationCacheHost(WebApplicationCacheHostClient* client)
    818 {
    819     if (!m_webFrame->client())
    820         return nullptr;
    821     return adoptPtr(m_webFrame->client()->createApplicationCacheHost(m_webFrame, client));
    822 }
    823 
    824 void FrameLoaderClientImpl::didStopAllLoaders()
    825 {
    826     if (m_webFrame->client())
    827         m_webFrame->client()->didAbortLoading(m_webFrame);
    828 }
    829 
    830 void FrameLoaderClientImpl::dispatchDidChangeManifest()
    831 {
    832     if (m_webFrame->client())
    833         m_webFrame->client()->didChangeManifest(m_webFrame);
    834 }
    835 
    836 } // namespace blink
    837