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
100namespace blink {
101
102FrameLoaderClientImpl::FrameLoaderClientImpl(WebLocalFrameImpl* frame)
103    : m_webFrame(frame)
104{
105}
106
107FrameLoaderClientImpl::~FrameLoaderClientImpl()
108{
109}
110
111void 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
129void FrameLoaderClientImpl::documentElementAvailable()
130{
131    if (m_webFrame->client())
132        m_webFrame->client()->didCreateDocumentElement(m_webFrame);
133}
134
135void 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
144void 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
150bool 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
160void FrameLoaderClientImpl::didChangeScrollOffset()
161{
162    if (m_webFrame->client())
163        m_webFrame->client()->didChangeScrollOffset(m_webFrame);
164}
165
166void FrameLoaderClientImpl::didUpdateCurrentHistoryItem()
167{
168    if (m_webFrame->client())
169        m_webFrame->client()->didUpdateCurrentHistoryItem(m_webFrame);
170}
171
172void FrameLoaderClientImpl::didRemoveAllPendingStylesheet()
173{
174    WebViewImpl* webview = m_webFrame->viewImpl();
175    if (webview)
176        webview->didRemoveAllPendingStylesheet(m_webFrame);
177}
178
179bool FrameLoaderClientImpl::allowScript(bool enabledPerSettings)
180{
181    if (m_webFrame->permissionClient())
182        return m_webFrame->permissionClient()->allowScript(enabledPerSettings);
183
184    return enabledPerSettings;
185}
186
187bool 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
195bool FrameLoaderClientImpl::allowPlugins(bool enabledPerSettings)
196{
197    if (m_webFrame->permissionClient())
198        return m_webFrame->permissionClient()->allowPlugins(enabledPerSettings);
199
200    return enabledPerSettings;
201}
202
203bool 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
211bool FrameLoaderClientImpl::allowMedia(const KURL& mediaURL)
212{
213    if (m_webFrame->permissionClient())
214        return m_webFrame->permissionClient()->allowMedia(mediaURL);
215
216    return true;
217}
218
219bool 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
227bool 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
235void FrameLoaderClientImpl::didNotAllowScript()
236{
237    if (m_webFrame->permissionClient())
238        m_webFrame->permissionClient()->didNotAllowScript();
239}
240
241void FrameLoaderClientImpl::didNotAllowPlugins()
242{
243    if (m_webFrame->permissionClient())
244        m_webFrame->permissionClient()->didNotAllowPlugins();
245
246}
247
248bool FrameLoaderClientImpl::hasWebView() const
249{
250    return m_webFrame->viewImpl();
251}
252
253Frame* FrameLoaderClientImpl::opener() const
254{
255    return toCoreFrame(m_webFrame->opener());
256}
257
258void FrameLoaderClientImpl::setOpener(Frame* opener)
259{
260    m_webFrame->setOpener(WebFrame::fromFrame(opener));
261}
262
263Frame* FrameLoaderClientImpl::parent() const
264{
265    return toCoreFrame(m_webFrame->parent());
266}
267
268Frame* FrameLoaderClientImpl::top() const
269{
270    return toCoreFrame(m_webFrame->top());
271}
272
273Frame* FrameLoaderClientImpl::previousSibling() const
274{
275    return toCoreFrame(m_webFrame->previousSibling());
276}
277
278Frame* FrameLoaderClientImpl::nextSibling() const
279{
280    return toCoreFrame(m_webFrame->nextSibling());
281}
282
283Frame* FrameLoaderClientImpl::firstChild() const
284{
285    return toCoreFrame(m_webFrame->firstChild());
286}
287
288Frame* FrameLoaderClientImpl::lastChild() const
289{
290    return toCoreFrame(m_webFrame->lastChild());
291}
292
293void 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
315void 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
328void 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
338void 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
345void FrameLoaderClientImpl::dispatchDidFinishLoading(DocumentLoader* loader,
346                                                    unsigned long identifier)
347{
348    if (m_webFrame->client())
349        m_webFrame->client()->didFinishResourceLoad(m_webFrame, identifier);
350}
351
352void FrameLoaderClientImpl::dispatchDidFinishDocumentLoad()
353{
354    if (m_webFrame->client())
355        m_webFrame->client()->didFinishDocumentLoad(m_webFrame);
356}
357
358void 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
364void FrameLoaderClientImpl::dispatchDidHandleOnloadEvents()
365{
366    if (m_webFrame->client())
367        m_webFrame->client()->didHandleOnloadEvents(m_webFrame);
368}
369
370void FrameLoaderClientImpl::dispatchDidReceiveServerRedirectForProvisionalLoad()
371{
372    if (m_webFrame->client())
373        m_webFrame->client()->didReceiveServerRedirectForProvisionalLoad(m_webFrame);
374}
375
376void 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
384void FrameLoaderClientImpl::dispatchWillClose()
385{
386    if (m_webFrame->client())
387        m_webFrame->client()->willClose(m_webFrame);
388}
389
390void FrameLoaderClientImpl::dispatchDidStartProvisionalLoad(bool isTransitionNavigation)
391{
392    if (m_webFrame->client())
393        m_webFrame->client()->didStartProvisionalLoad(m_webFrame, isTransitionNavigation);
394}
395
396void FrameLoaderClientImpl::dispatchDidReceiveTitle(const String& title)
397{
398    if (m_webFrame->client())
399        m_webFrame->client()->didReceiveTitle(m_webFrame, title, WebTextDirectionLeftToRight);
400}
401
402void FrameLoaderClientImpl::dispatchDidChangeIcons(IconType type)
403{
404    if (m_webFrame->client())
405        m_webFrame->client()->didChangeIcon(m_webFrame, static_cast<WebIconURL::Type>(type));
406}
407
408void 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
415void 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
424void 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
436void 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
451void FrameLoaderClientImpl::dispatchDidFirstVisuallyNonEmptyLayout()
452{
453    if (m_webFrame->client())
454        m_webFrame->client()->didFirstVisuallyNonEmptyLayout(m_webFrame);
455}
456
457void FrameLoaderClientImpl::dispatchDidChangeThemeColor()
458{
459    if (m_webFrame->client())
460        m_webFrame->client()->didChangeThemeColor();
461}
462
463NavigationPolicy 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
482void 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
488void 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
496void FrameLoaderClientImpl::dispatchWillSendSubmitEvent(HTMLFormElement* form)
497{
498    if (m_webFrame->client())
499        m_webFrame->client()->willSendSubmitEvent(m_webFrame, WebFormElement(form));
500}
501
502void FrameLoaderClientImpl::dispatchWillSubmitForm(HTMLFormElement* form)
503{
504    if (m_webFrame->client())
505        m_webFrame->client()->willSubmitForm(m_webFrame, WebFormElement(form));
506}
507
508void FrameLoaderClientImpl::didStartLoading(LoadStartType loadStartType)
509{
510    if (m_webFrame->client())
511        m_webFrame->client()->didStartLoading(loadStartType == NavigationToDifferentDocument);
512}
513
514void FrameLoaderClientImpl::progressEstimateChanged(double progressEstimate)
515{
516    if (m_webFrame->client())
517        m_webFrame->client()->didChangeLoadProgress(progressEstimate);
518}
519
520void FrameLoaderClientImpl::didStopLoading()
521{
522    if (m_webFrame->client())
523        m_webFrame->client()->didStopLoading();
524}
525
526void 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
537bool 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
552void FrameLoaderClientImpl::didAccessInitialDocument()
553{
554    if (m_webFrame->client())
555        m_webFrame->client()->didAccessInitialDocument(m_webFrame);
556}
557
558void FrameLoaderClientImpl::didDisplayInsecureContent()
559{
560    if (m_webFrame->client())
561        m_webFrame->client()->didDisplayInsecureContent(m_webFrame);
562}
563
564void 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
570void FrameLoaderClientImpl::didDetectXSS(const KURL& insecureURL, bool didBlockEntirePage)
571{
572    if (m_webFrame->client())
573        m_webFrame->client()->didDetectXSS(m_webFrame, insecureURL, didBlockEntirePage);
574}
575
576void FrameLoaderClientImpl::didDispatchPingLoader(const KURL& url)
577{
578    if (m_webFrame->client())
579        m_webFrame->client()->didDispatchPingLoader(m_webFrame, url);
580}
581
582void 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
588PassRefPtr<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
596String 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
605String 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.
615void FrameLoaderClientImpl::transitionToCommittedForNewPage()
616{
617    m_webFrame->createFrameView();
618}
619
620PassRefPtrWillBeRawPtr<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
631bool 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
639PassRefPtr<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
675PassRefPtr<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
685ObjectContentType 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
728PassOwnPtr<WebPluginLoadObserver> FrameLoaderClientImpl::pluginLoadObserver(DocumentLoader* loader)
729{
730    return WebDataSourceImpl::fromDocumentLoader(loader)->releasePluginLoadObserver();
731}
732
733WebCookieJar* FrameLoaderClientImpl::cookieJar() const
734{
735    if (!m_webFrame->client())
736        return 0;
737    return m_webFrame->client()->cookieJar(m_webFrame);
738}
739
740bool 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
749void FrameLoaderClientImpl::didChangeName(const String& name)
750{
751    if (!m_webFrame->client())
752        return;
753    m_webFrame->client()->didChangeName(m_webFrame, name);
754}
755
756void FrameLoaderClientImpl::dispatchWillOpenSocketStream(SocketStreamHandle* handle)
757{
758    m_webFrame->client()->willOpenSocketStream(SocketStreamHandleInternal::toWebSocketStreamHandle(handle));
759}
760
761void FrameLoaderClientImpl::dispatchWillOpenWebSocket(WebSocketHandle* handle)
762{
763    m_webFrame->client()->willOpenWebSocket(handle);
764}
765
766void FrameLoaderClientImpl::dispatchWillStartUsingPeerConnectionHandler(WebRTCPeerConnectionHandler* handler)
767{
768    m_webFrame->client()->willStartUsingPeerConnectionHandler(webFrame(), handler);
769}
770
771void FrameLoaderClientImpl::didRequestAutocomplete(HTMLFormElement* form)
772{
773    if (m_webFrame->viewImpl() && m_webFrame->viewImpl()->autofillClient())
774        m_webFrame->viewImpl()->autofillClient()->didRequestAutocomplete(WebFormElement(form));
775}
776
777bool 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
785void FrameLoaderClientImpl::didLoseWebGLContext(int arbRobustnessContextLostReason)
786{
787    if (m_webFrame->client())
788        m_webFrame->client()->didLoseWebGLContext(m_webFrame, arbRobustnessContextLostReason);
789}
790
791void 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
800PassOwnPtr<WebServiceWorkerProvider> FrameLoaderClientImpl::createServiceWorkerProvider()
801{
802    if (!m_webFrame->client())
803        return nullptr;
804    return adoptPtr(m_webFrame->client()->createServiceWorkerProvider(m_webFrame));
805}
806
807bool FrameLoaderClientImpl::isControlledByServiceWorker()
808{
809    return m_webFrame->client() && m_webFrame->client()->isControlledByServiceWorker();
810}
811
812SharedWorkerRepositoryClient* FrameLoaderClientImpl::sharedWorkerRepositoryClient()
813{
814    return m_webFrame->sharedWorkerRepositoryClient();
815}
816
817PassOwnPtr<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
824void FrameLoaderClientImpl::didStopAllLoaders()
825{
826    if (m_webFrame->client())
827        m_webFrame->client()->didAbortLoading(m_webFrame);
828}
829
830void FrameLoaderClientImpl::dispatchDidChangeManifest()
831{
832    if (m_webFrame->client())
833        m_webFrame->client()->didChangeManifest(m_webFrame);
834}
835
836} // namespace blink
837