FrameLoaderClientImpl.cpp [plain text]
#include "config.h"
#include "FrameLoaderClientImpl.h"
#include "Chrome.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "FormState.h"
#include "FrameLoader.h"
#include "FrameLoadRequest.h"
#include "HTTPParsers.h"
#include "HistoryItem.h"
#include "HitTestResult.h"
#include "HTMLAppletElement.h"
#include "HTMLFormElement.h" // needed by FormState.h
#include "HTMLNames.h"
#include "MIMETypeRegistry.h"
#include "MouseEvent.h"
#include "Page.h"
#include "PlatformString.h"
#include "PluginData.h"
#include "PluginDataChromium.h"
#include "StringExtras.h"
#include "WebDataSourceImpl.h"
#include "WebDevToolsAgentPrivate.h"
#include "WebFormElement.h"
#include "WebFrameClient.h"
#include "WebFrameImpl.h"
#include "WebKit.h"
#include "WebKitClient.h"
#include "WebMimeRegistry.h"
#include "WebNode.h"
#include "WebPlugin.h"
#include "WebPluginContainerImpl.h"
#include "WebPluginLoadObserver.h"
#include "WebPluginParams.h"
#include "WebSecurityOrigin.h"
#include "WebURL.h"
#include "WebURLError.h"
#include "WebVector.h"
#include "WebViewClient.h"
#include "WebViewImpl.h"
#include "WindowFeatures.h"
#include "WrappedResourceRequest.h"
#include "WrappedResourceResponse.h"
#include <wtf/text/CString.h>
using namespace WebCore;
namespace WebKit {
static const char internalErrorDomain[] = "WebKit";
enum {
PolicyChangeError = -10000,
};
FrameLoaderClientImpl::FrameLoaderClientImpl(WebFrameImpl* frame)
: m_webFrame(frame)
, m_hasRepresentation(false)
, m_sentInitialResponseToPlugin(false)
, m_nextNavigationPolicy(WebNavigationPolicyIgnore)
{
}
FrameLoaderClientImpl::~FrameLoaderClientImpl()
{
}
void FrameLoaderClientImpl::frameLoaderDestroyed()
{
m_webFrame->closing();
m_webFrame->deref();
}
void FrameLoaderClientImpl::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*)
{
if (m_webFrame->client())
m_webFrame->client()->didClearWindowObject(m_webFrame);
WebViewImpl* webview = m_webFrame->viewImpl();
if (webview->devToolsAgentPrivate())
webview->devToolsAgentPrivate()->didClearWindowObject(m_webFrame);
}
void FrameLoaderClientImpl::documentElementAvailable()
{
if (m_webFrame->client())
m_webFrame->client()->didCreateDocumentElement(m_webFrame);
}
void FrameLoaderClientImpl::didCreateScriptContextForFrame()
{
if (m_webFrame->client())
m_webFrame->client()->didCreateScriptContext(m_webFrame);
}
void FrameLoaderClientImpl::didDestroyScriptContextForFrame()
{
if (m_webFrame->client())
m_webFrame->client()->didDestroyScriptContext(m_webFrame);
}
void FrameLoaderClientImpl::didCreateIsolatedScriptContext()
{
if (m_webFrame->client())
m_webFrame->client()->didCreateIsolatedScriptContext(m_webFrame);
}
void FrameLoaderClientImpl::didPerformFirstNavigation() const
{
}
void FrameLoaderClientImpl::registerForIconNotification(bool)
{
}
void FrameLoaderClientImpl::didChangeScrollOffset()
{
if (m_webFrame->client())
m_webFrame->client()->didChangeScrollOffset(m_webFrame);
}
bool FrameLoaderClientImpl::allowJavaScript(bool enabledPerSettings)
{
if (m_webFrame->client())
return m_webFrame->client()->allowScript(m_webFrame, enabledPerSettings);
return enabledPerSettings;
}
bool FrameLoaderClientImpl::allowPlugins(bool enabledPerSettings)
{
if (m_webFrame->client())
return m_webFrame->client()->allowPlugins(m_webFrame, enabledPerSettings);
return enabledPerSettings;
}
bool FrameLoaderClientImpl::allowImages(bool enabledPerSettings)
{
if (m_webFrame->client())
return m_webFrame->client()->allowImages(m_webFrame, enabledPerSettings);
return enabledPerSettings;
}
void FrameLoaderClientImpl::didNotAllowScript()
{
if (m_webFrame->client())
m_webFrame->client()->didNotAllowScript(m_webFrame);
}
void FrameLoaderClientImpl::didNotAllowPlugins()
{
if (m_webFrame->client())
m_webFrame->client()->didNotAllowPlugins(m_webFrame);
}
bool FrameLoaderClientImpl::hasWebView() const
{
return m_webFrame->viewImpl();
}
bool FrameLoaderClientImpl::hasFrameView() const
{
return m_webFrame->viewImpl();
}
void FrameLoaderClientImpl::makeDocumentView()
{
m_webFrame->createFrameView();
}
void FrameLoaderClientImpl::makeRepresentation(DocumentLoader*)
{
m_hasRepresentation = true;
}
void FrameLoaderClientImpl::forceLayout()
{
}
void FrameLoaderClientImpl::forceLayoutForNonHTML()
{
}
void FrameLoaderClientImpl::setCopiesOnScroll()
{
}
void FrameLoaderClientImpl::detachedFromParent2()
{
}
void FrameLoaderClientImpl::detachedFromParent3()
{
m_webFrame->frame()->script()->proxy()->clearForClose();
m_webFrame->setClient(0);
}
void FrameLoaderClientImpl::assignIdentifierToInitialRequest(
unsigned long identifier, DocumentLoader* loader,
const ResourceRequest& request)
{
if (m_webFrame->client()) {
WrappedResourceRequest webreq(request);
m_webFrame->client()->assignIdentifierToRequest(
m_webFrame, identifier, webreq);
}
}
static void setTargetTypeFromLoader(ResourceRequest& request, DocumentLoader* loader)
{
if (loader == loader->frameLoader()->provisionalDocumentLoader()) {
ResourceRequest::TargetType type;
if (loader->frameLoader()->isLoadingMainFrame())
type = ResourceRequest::TargetIsMainFrame;
else
type = ResourceRequest::TargetIsSubframe;
request.setTargetType(type);
}
}
void FrameLoaderClientImpl::dispatchWillSendRequest(
DocumentLoader* loader, unsigned long identifier, ResourceRequest& request,
const ResourceResponse& redirectResponse)
{
if (loader) {
setTargetTypeFromLoader(request, loader);
if (loader == loader->frameLoader()->provisionalDocumentLoader()
&& request.httpMethod() == "POST"
&& isBackForwardLoadType(loader->frameLoader()->loadType()))
request.setCachePolicy(ReturnCacheDataDontLoad);
}
if (request.url().isEmpty())
request.setURL(KURL(ParsedURLString, "about:blank"));
if (request.firstPartyForCookies().isEmpty())
request.setFirstPartyForCookies(KURL(ParsedURLString, "about:blank"));
if (m_webFrame->client()) {
WrappedResourceRequest webreq(request);
WrappedResourceResponse webresp(redirectResponse);
m_webFrame->client()->willSendRequest(
m_webFrame, identifier, webreq, webresp);
}
}
bool FrameLoaderClientImpl::shouldUseCredentialStorage(
DocumentLoader*, unsigned long identifier)
{
return true;
}
void FrameLoaderClientImpl::dispatchDidReceiveAuthenticationChallenge(
DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&)
{
}
void FrameLoaderClientImpl::dispatchDidCancelAuthenticationChallenge(
DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&)
{
}
void FrameLoaderClientImpl::dispatchDidReceiveResponse(DocumentLoader* loader,
unsigned long identifier,
const ResourceResponse& response)
{
if (m_webFrame->client()) {
WrappedResourceResponse webresp(response);
m_webFrame->client()->didReceiveResponse(m_webFrame, identifier, webresp);
}
}
void FrameLoaderClientImpl::dispatchDidReceiveContentLength(
DocumentLoader* loader,
unsigned long identifier,
int lengthReceived)
{
}
void FrameLoaderClientImpl::dispatchDidFinishLoading(DocumentLoader* loader,
unsigned long identifier)
{
if (m_webFrame->client())
m_webFrame->client()->didFinishResourceLoad(m_webFrame, identifier);
}
void FrameLoaderClientImpl::dispatchDidFailLoading(DocumentLoader* loader,
unsigned long identifier,
const ResourceError& error)
{
if (m_webFrame->client())
m_webFrame->client()->didFailResourceLoad(m_webFrame, identifier, error);
}
void FrameLoaderClientImpl::dispatchDidFinishDocumentLoad()
{
m_webFrame->clearPasswordListeners();
if (m_webFrame->client())
m_webFrame->client()->didFinishDocumentLoad(m_webFrame);
}
bool FrameLoaderClientImpl::dispatchDidLoadResourceFromMemoryCache(
DocumentLoader* loader,
const ResourceRequest& request,
const ResourceResponse& response,
int length)
{
if (m_webFrame->client()) {
WrappedResourceRequest webreq(request);
WrappedResourceResponse webresp(response);
m_webFrame->client()->didLoadResourceFromMemoryCache(
m_webFrame, webreq, webresp);
}
return false; }
void FrameLoaderClientImpl::dispatchDidHandleOnloadEvents()
{
if (m_webFrame->client())
m_webFrame->client()->didHandleOnloadEvents(m_webFrame);
}
void FrameLoaderClientImpl::dispatchDidReceiveServerRedirectForProvisionalLoad()
{
WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl();
if (!ds) {
ASSERT_NOT_REACHED();
return;
}
if (ds->request().isNull())
return;
ASSERT(ds->hasRedirectChain());
ds->appendRedirect(ds->request().url());
if (m_webFrame->client())
m_webFrame->client()->didReceiveServerRedirectForProvisionalLoad(m_webFrame);
}
void FrameLoaderClientImpl::dispatchDidCancelClientRedirect()
{
if (m_webFrame->client()) {
m_expectedClientRedirectSrc = KURL();
m_expectedClientRedirectDest = KURL();
m_webFrame->client()->didCancelClientRedirect(m_webFrame);
}
}
void FrameLoaderClientImpl::dispatchWillPerformClientRedirect(
const KURL& url,
double interval,
double fireDate)
{
m_expectedClientRedirectSrc = m_webFrame->url();
m_expectedClientRedirectDest = url;
if (m_expectedClientRedirectDest.isLocalFile()
&& m_expectedClientRedirectSrc.protocolInHTTPFamily()) {
m_expectedClientRedirectSrc = KURL();
m_expectedClientRedirectDest = KURL();
return;
}
if (m_webFrame->client()) {
m_webFrame->client()->willPerformClientRedirect(
m_webFrame,
m_expectedClientRedirectSrc,
m_expectedClientRedirectDest,
static_cast<unsigned int>(interval),
static_cast<unsigned int>(fireDate));
}
}
void FrameLoaderClientImpl::dispatchDidNavigateWithinPage()
{
WebViewImpl* webView = m_webFrame->viewImpl();
bool loaderCompleted =
!webView->page()->mainFrame()->loader()->activeDocumentLoader()->isLoadingInAPISense();
if (webView->client() && loaderCompleted)
webView->client()->didStartLoading();
HistoryItem* currentItem = m_webFrame->frame()->loader()->history()->currentItem();
bool isHashChange = !currentItem || !currentItem->stateObject();
WebDataSourceImpl* ds = m_webFrame->dataSourceImpl();
ASSERT(ds); if (ds) {
KURL url = ds->request().url();
KURL chainEnd;
if (ds->hasRedirectChain()) {
chainEnd = ds->endOfRedirectChain();
ds->clearRedirectChain();
}
if (isHashChange) {
bool wasClientRedirect =
(url == m_expectedClientRedirectDest && chainEnd == m_expectedClientRedirectSrc)
|| !m_webFrame->isProcessingUserGesture();
if (wasClientRedirect) {
if (m_webFrame->client())
m_webFrame->client()->didCompleteClientRedirect(m_webFrame, chainEnd);
ds->appendRedirect(chainEnd);
m_expectedClientRedirectSrc = KURL();
m_expectedClientRedirectDest = KURL();
}
}
ds->appendRedirect(url);
}
bool isNewNavigation;
webView->didCommitLoad(&isNewNavigation);
if (m_webFrame->client())
m_webFrame->client()->didNavigateWithinPage(m_webFrame, isNewNavigation);
if (webView->client() && loaderCompleted)
webView->client()->didStopLoading();
}
void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage()
{
if (m_webFrame)
m_webFrame->client()->didChangeLocationWithinPage(m_webFrame);
}
void FrameLoaderClientImpl::dispatchDidPushStateWithinPage()
{
dispatchDidNavigateWithinPage();
}
void FrameLoaderClientImpl::dispatchDidReplaceStateWithinPage()
{
dispatchDidNavigateWithinPage();
}
void FrameLoaderClientImpl::dispatchDidPopStateWithinPage()
{
}
void FrameLoaderClientImpl::dispatchWillClose()
{
if (m_webFrame->client())
m_webFrame->client()->willClose(m_webFrame);
}
void FrameLoaderClientImpl::dispatchDidReceiveIcon()
{
ASSERT_NOT_REACHED();
}
void FrameLoaderClientImpl::dispatchDidStartProvisionalLoad()
{
WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl();
if (!ds) {
ASSERT_NOT_REACHED();
return;
}
KURL url = ds->request().url();
ASSERT(!ds->hasRedirectChain());
bool completingClientRedirect = false;
if (m_expectedClientRedirectSrc.isValid()) {
ASSERT(m_expectedClientRedirectDest.protocolIs("javascript")
|| m_expectedClientRedirectDest == url);
ds->appendRedirect(m_expectedClientRedirectSrc);
completingClientRedirect = true;
}
ds->appendRedirect(url);
if (m_webFrame->client()) {
m_webFrame->client()->didStartProvisionalLoad(m_webFrame);
if (completingClientRedirect) {
m_webFrame->client()->didCompleteClientRedirect(
m_webFrame, m_expectedClientRedirectSrc);
}
}
}
void FrameLoaderClientImpl::dispatchDidReceiveTitle(const String& title)
{
if (m_webFrame->client())
m_webFrame->client()->didReceiveTitle(m_webFrame, title);
}
void FrameLoaderClientImpl::dispatchDidChangeIcons()
{
if (m_webFrame->client())
m_webFrame->client()->didChangeIcons(m_webFrame);
}
void FrameLoaderClientImpl::dispatchDidCommitLoad()
{
WebViewImpl* webview = m_webFrame->viewImpl();
bool isNewNavigation;
webview->didCommitLoad(&isNewNavigation);
if (m_webFrame->client())
m_webFrame->client()->didCommitProvisionalLoad(m_webFrame, isNewNavigation);
if (webview->devToolsAgentPrivate())
webview->devToolsAgentPrivate()->didCommitProvisionalLoad(m_webFrame, isNewNavigation);
}
void FrameLoaderClientImpl::dispatchDidFailProvisionalLoad(
const ResourceError& error)
{
if (error.domain() == internalErrorDomain
&& error.errorCode() == PolicyChangeError) {
m_webFrame->didFail(cancelledError(error.failingURL()), true);
return;
}
OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver();
m_webFrame->didFail(error, true);
if (observer)
observer->didFailLoading(error);
}
void FrameLoaderClientImpl::dispatchDidFailLoad(const ResourceError& error)
{
OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver();
m_webFrame->didFail(error, false);
if (observer)
observer->didFailLoading(error);
}
void FrameLoaderClientImpl::dispatchDidFinishLoad()
{
OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver();
if (m_webFrame->client())
m_webFrame->client()->didFinishLoad(m_webFrame);
if (observer)
observer->didFinishLoading();
}
void FrameLoaderClientImpl::dispatchDidFirstLayout()
{
if (m_webFrame->client())
m_webFrame->client()->didFirstLayout(m_webFrame);
}
void FrameLoaderClientImpl::dispatchDidFirstVisuallyNonEmptyLayout()
{
if (m_webFrame->client())
m_webFrame->client()->didFirstVisuallyNonEmptyLayout(m_webFrame);
}
Frame* FrameLoaderClientImpl::dispatchCreatePage()
{
struct WindowFeatures features;
Page* newPage = m_webFrame->frame()->page()->chrome()->createWindow(
m_webFrame->frame(), FrameLoadRequest(), features);
ASSERT(m_nextNavigationPolicy != WebNavigationPolicyIgnore);
WebNavigationPolicy policy = m_nextNavigationPolicy;
m_nextNavigationPolicy = WebNavigationPolicyIgnore;
if (!newPage)
return 0;
WebViewImpl::fromPage(newPage)->setInitialNavigationPolicy(policy);
return newPage->mainFrame();
}
void FrameLoaderClientImpl::dispatchShow()
{
WebViewImpl* webView = m_webFrame->viewImpl();
if (webView && webView->client())
webView->client()->show(webView->initialNavigationPolicy());
}
void FrameLoaderClientImpl::dispatchDecidePolicyForMIMEType(
FramePolicyFunction function,
const String& mimeType,
const ResourceRequest&)
{
const ResourceResponse& response =
m_webFrame->frame()->loader()->activeDocumentLoader()->response();
PolicyAction action;
int statusCode = response.httpStatusCode();
if (statusCode == 204 || statusCode == 205) {
action = PolicyIgnore;
} else if (WebCore::contentDispositionType(response.httpHeaderField("Content-Disposition")) == WebCore::ContentDispositionAttachment) {
action = PolicyIgnore;
} else if (!canShowMIMEType(mimeType)) {
action = PolicyIgnore;
} else {
action = PolicyUse;
}
(m_webFrame->frame()->loader()->policyChecker()->*function)(action);
}
void FrameLoaderClientImpl::dispatchDecidePolicyForNewWindowAction(
FramePolicyFunction function,
const NavigationAction& action,
const ResourceRequest& request,
PassRefPtr<FormState> formState,
const String& frameName)
{
WebNavigationPolicy navigationPolicy;
if (!actionSpecifiesNavigationPolicy(action, &navigationPolicy))
navigationPolicy = WebNavigationPolicyNewForegroundTab;
PolicyAction policyAction;
if (navigationPolicy == WebNavigationPolicyDownload)
policyAction = PolicyDownload;
else {
policyAction = PolicyUse;
m_nextNavigationPolicy = navigationPolicy;
}
(m_webFrame->frame()->loader()->policyChecker()->*function)(policyAction);
}
void FrameLoaderClientImpl::dispatchDecidePolicyForNavigationAction(
FramePolicyFunction function,
const NavigationAction& action,
const ResourceRequest& request,
PassRefPtr<FormState> formState) {
PolicyAction policyAction = PolicyIgnore;
if (m_webFrame->client() && !request.url().isNull()) {
WebNavigationPolicy navigationPolicy = WebNavigationPolicyCurrentTab;
actionSpecifiesNavigationPolicy(action, &navigationPolicy);
const WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl();
if (ds) {
KURL url = ds->request().url();
ASSERT(!url.protocolIs(backForwardNavigationScheme));
bool isRedirect = ds->hasRedirectChain();
WebNavigationType webnavType =
WebDataSourceImpl::toWebNavigationType(action.type());
RefPtr<Node> node;
for (const Event* event = action.event(); event; event = event->underlyingEvent()) {
if (event->isMouseEvent()) {
const MouseEvent* mouseEvent =
static_cast<const MouseEvent*>(event);
node = m_webFrame->frame()->eventHandler()->hitTestResultAtPoint(
mouseEvent->absoluteLocation(), false).innerNonSharedNode();
break;
}
}
WebNode originatingNode(node);
navigationPolicy = m_webFrame->client()->decidePolicyForNavigation(
m_webFrame, ds->request(), webnavType, originatingNode,
navigationPolicy, isRedirect);
}
if (navigationPolicy == WebNavigationPolicyCurrentTab)
policyAction = PolicyUse;
else if (navigationPolicy == WebNavigationPolicyDownload)
policyAction = PolicyDownload;
else {
if (navigationPolicy != WebNavigationPolicyIgnore) {
WrappedResourceRequest webreq(request);
m_webFrame->client()->loadURLExternally(m_webFrame, webreq, navigationPolicy);
}
policyAction = PolicyIgnore;
}
}
(m_webFrame->frame()->loader()->policyChecker()->*function)(policyAction);
}
void FrameLoaderClientImpl::cancelPolicyCheck()
{
}
void FrameLoaderClientImpl::dispatchUnableToImplementPolicy(const ResourceError& error)
{
m_webFrame->client()->unableToImplementPolicyWithError(m_webFrame, error);
}
void FrameLoaderClientImpl::dispatchWillSendSubmitEvent(HTMLFormElement* form)
{
if (m_webFrame->client())
m_webFrame->client()->willSendSubmitEvent(m_webFrame, WebFormElement(form));
}
void FrameLoaderClientImpl::dispatchWillSubmitForm(FramePolicyFunction function,
PassRefPtr<FormState> formState)
{
if (m_webFrame->client())
m_webFrame->client()->willSubmitForm(m_webFrame, WebFormElement(formState->form()));
(m_webFrame->frame()->loader()->policyChecker()->*function)(PolicyUse);
}
void FrameLoaderClientImpl::dispatchDidLoadMainResource(DocumentLoader*)
{
}
void FrameLoaderClientImpl::revertToProvisionalState(DocumentLoader*)
{
m_hasRepresentation = true;
}
void FrameLoaderClientImpl::setMainDocumentError(DocumentLoader*,
const ResourceError& error)
{
if (m_pluginWidget.get()) {
if (m_sentInitialResponseToPlugin) {
m_pluginWidget->didFailLoading(error);
m_sentInitialResponseToPlugin = false;
}
m_pluginWidget = 0;
}
}
void FrameLoaderClientImpl::postProgressStartedNotification()
{
WebViewImpl* webview = m_webFrame->viewImpl();
if (webview && webview->client())
webview->client()->didStartLoading();
}
void FrameLoaderClientImpl::postProgressEstimateChangedNotification()
{
}
void FrameLoaderClientImpl::postProgressFinishedNotification()
{
WebViewImpl* webview = m_webFrame->viewImpl();
if (webview && webview->client())
webview->client()->didStopLoading();
}
void FrameLoaderClientImpl::setMainFrameDocumentReady(bool ready)
{
}
void FrameLoaderClientImpl::startDownload(const ResourceRequest& request)
{
if (m_webFrame->client()) {
WrappedResourceRequest webreq(request);
m_webFrame->client()->loadURLExternally(
m_webFrame, webreq, WebNavigationPolicyDownload);
}
}
void FrameLoaderClientImpl::willChangeTitle(DocumentLoader*)
{
}
void FrameLoaderClientImpl::didChangeTitle(DocumentLoader*)
{
}
void FrameLoaderClientImpl::committedLoad(DocumentLoader* loader, const char* data, int length)
{
if (!m_pluginWidget.get()) {
if (m_webFrame->client()) {
bool preventDefault = false;
m_webFrame->client()->didReceiveDocumentData(m_webFrame, data, length, preventDefault);
if (!preventDefault)
m_webFrame->commitDocumentData(data, length);
}
}
if (m_webFrame->frame()->document()
&& m_webFrame->frame()->document()->isMediaDocument())
loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
if (m_pluginWidget.get()) {
if (!m_sentInitialResponseToPlugin) {
m_sentInitialResponseToPlugin = true;
m_pluginWidget->didReceiveResponse(
m_webFrame->frame()->loader()->activeDocumentLoader()->response());
}
m_pluginWidget->didReceiveData(data, length);
}
}
void FrameLoaderClientImpl::finishedLoading(DocumentLoader* dl)
{
if (m_pluginWidget.get()) {
m_pluginWidget->didFinishLoading();
m_pluginWidget = 0;
m_sentInitialResponseToPlugin = false;
} else {
if (m_hasRepresentation)
dl->frameLoader()->writer()->setEncoding("", false);
}
}
void FrameLoaderClientImpl::updateGlobalHistory()
{
}
void FrameLoaderClientImpl::updateGlobalHistoryRedirectLinks()
{
}
bool FrameLoaderClientImpl::shouldGoToHistoryItem(HistoryItem* item) const
{
const KURL& url = item->url();
if (!url.protocolIs(backForwardNavigationScheme))
return true;
bool ok;
int offset = url.lastPathComponent().toIntStrict(&ok);
if (!ok) {
ASSERT_NOT_REACHED();
return false;
}
WebViewImpl* webview = m_webFrame->viewImpl();
if (webview->client())
webview->client()->navigateBackForwardSoon(offset);
return false;
}
void FrameLoaderClientImpl::dispatchDidAddBackForwardItem(HistoryItem*) const
{
}
void FrameLoaderClientImpl::dispatchDidRemoveBackForwardItem(HistoryItem*) const
{
}
void FrameLoaderClientImpl::dispatchDidChangeBackForwardIndex() const
{
}
void FrameLoaderClientImpl::didDisplayInsecureContent()
{
if (m_webFrame->client())
m_webFrame->client()->didDisplayInsecureContent(m_webFrame);
}
void FrameLoaderClientImpl::didRunInsecureContent(SecurityOrigin* origin)
{
if (m_webFrame->client())
m_webFrame->client()->didRunInsecureContent(m_webFrame, WebSecurityOrigin(origin));
}
ResourceError FrameLoaderClientImpl::blockedError(const ResourceRequest&)
{
return ResourceError();
}
ResourceError FrameLoaderClientImpl::cancelledError(const ResourceRequest& request)
{
if (!m_webFrame->client())
return ResourceError();
return m_webFrame->client()->cancelledError(
m_webFrame, WrappedResourceRequest(request));
}
ResourceError FrameLoaderClientImpl::cannotShowURLError(const ResourceRequest& request)
{
if (!m_webFrame->client())
return ResourceError();
return m_webFrame->client()->cannotHandleRequestError(
m_webFrame, WrappedResourceRequest(request));
}
ResourceError FrameLoaderClientImpl::interruptForPolicyChangeError(
const ResourceRequest& request)
{
return ResourceError(internalErrorDomain, PolicyChangeError,
request.url().string(), String());
}
ResourceError FrameLoaderClientImpl::cannotShowMIMETypeError(const ResourceResponse&)
{
return ResourceError();
}
ResourceError FrameLoaderClientImpl::fileDoesNotExistError(const ResourceResponse&)
{
return ResourceError();
}
ResourceError FrameLoaderClientImpl::pluginWillHandleLoadError(const ResourceResponse&)
{
return ResourceError();
}
bool FrameLoaderClientImpl::shouldFallBack(const ResourceError& error)
{
ResourceError c = cancelledError(ResourceRequest());
return error.errorCode() != c.errorCode() || error.domain() != c.domain();
}
bool FrameLoaderClientImpl::canHandleRequest(const ResourceRequest& request) const
{
return m_webFrame->client()->canHandleRequest(
m_webFrame, WrappedResourceRequest(request));
}
bool FrameLoaderClientImpl::canShowMIMEType(const String& mimeType) const
{
if (webKitClient()->mimeRegistry()->supportsMIMEType(mimeType) == WebMimeRegistry::IsSupported)
return true;
PluginData* pluginData = m_webFrame->frame()->page()->pluginData();
return !mimeType.isEmpty() && pluginData && pluginData->supportsMimeType(mimeType);
}
bool FrameLoaderClientImpl::representationExistsForURLScheme(const String&) const
{
return false;
}
String FrameLoaderClientImpl::generatedMIMETypeForURLScheme(const String& scheme) const
{
String mimeType("x-apple-web-kit/");
mimeType.append(scheme.lower());
return mimeType;
}
void FrameLoaderClientImpl::frameLoadCompleted()
{
}
void FrameLoaderClientImpl::saveViewStateToItem(HistoryItem*)
{
}
void FrameLoaderClientImpl::restoreViewState()
{
}
void FrameLoaderClientImpl::provisionalLoadStarted()
{
}
void FrameLoaderClientImpl::didFinishLoad()
{
OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver();
if (observer)
observer->didFinishLoading();
}
void FrameLoaderClientImpl::prepareForDataSourceReplacement()
{
}
PassRefPtr<DocumentLoader> FrameLoaderClientImpl::createDocumentLoader(
const ResourceRequest& request,
const SubstituteData& data)
{
RefPtr<WebDataSourceImpl> ds = WebDataSourceImpl::create(request, data);
if (m_webFrame->client())
m_webFrame->client()->didCreateDataSource(m_webFrame, ds.get());
return ds.release();
}
void FrameLoaderClientImpl::setTitle(const String& title, const KURL& url)
{
}
String FrameLoaderClientImpl::userAgent(const KURL& url)
{
return webKitClient()->userAgent(url);
}
void FrameLoaderClientImpl::savePlatformDataToCachedFrame(CachedFrame*)
{
ASSERT_NOT_REACHED();
}
void FrameLoaderClientImpl::transitionToCommittedFromCachedFrame(CachedFrame*)
{
ASSERT_NOT_REACHED();
}
void FrameLoaderClientImpl::transitionToCommittedForNewPage()
{
makeDocumentView();
}
bool FrameLoaderClientImpl::canCachePage() const
{
return false;
}
void FrameLoaderClientImpl::download(ResourceHandle* handle,
const ResourceRequest& request,
const ResourceRequest& initialRequest,
const ResourceResponse& response)
{
ASSERT_NOT_REACHED();
}
PassRefPtr<Frame> FrameLoaderClientImpl::createFrame(
const KURL& url,
const String& name,
HTMLFrameOwnerElement* ownerElement,
const String& referrer,
bool allowsScrolling,
int marginWidth,
int marginHeight)
{
FrameLoadRequest frameRequest(ResourceRequest(url, referrer), name);
return m_webFrame->createChildFrame(frameRequest, ownerElement);
}
void FrameLoaderClientImpl::didTransferChildFrameToNewDocument()
{
ASSERT(m_webFrame->frame()->ownerElement());
WebFrameImpl* newParent = static_cast<WebFrameImpl*>(m_webFrame->parent());
if (!newParent || !newParent->client())
return;
m_webFrame->setClient(newParent->client());
}
PassRefPtr<Widget> FrameLoaderClientImpl::createPlugin(
const IntSize& size, HTMLPlugInElement* element,
const KURL& url,
const Vector<String>& paramNames,
const Vector<String>& paramValues,
const String& mimeType,
bool loadManually)
{
#if !OS(WINDOWS)
if (objectContentType(url, mimeType) != ObjectContentNetscapePlugin)
return 0;
#endif
if (!m_webFrame->client())
return 0;
WebPluginParams params;
params.url = url;
params.mimeType = mimeType;
params.attributeNames = paramNames;
params.attributeValues = paramValues;
params.loadManually = loadManually;
WebPlugin* webPlugin = m_webFrame->client()->createPlugin(m_webFrame, params);
if (!webPlugin)
return 0;
RefPtr<WebPluginContainerImpl> container =
WebPluginContainerImpl::create(element, webPlugin);
if (!webPlugin->initialize(container.get()))
return 0;
if (!element->renderer())
return 0;
return container;
}
void FrameLoaderClientImpl::redirectDataToPlugin(Widget* pluginWidget)
{
m_pluginWidget = static_cast<WebPluginContainerImpl*>(pluginWidget);
ASSERT(m_pluginWidget.get());
}
PassRefPtr<Widget> FrameLoaderClientImpl::createJavaAppletWidget(
const IntSize& size,
HTMLAppletElement* element,
const KURL& ,
const Vector<String>& paramNames,
const Vector<String>& paramValues)
{
return createPlugin(size, element, KURL(), paramNames, paramValues,
"application/x-java-applet", false);
}
ObjectContentType FrameLoaderClientImpl::objectContentType(
const KURL& url,
const String& explicitMimeType)
{
String mimeType = explicitMimeType;
if (mimeType.isEmpty()) {
String filename = url.lastPathComponent();
int extensionPos = filename.reverseFind('.');
if (extensionPos >= 0) {
String extension = filename.substring(extensionPos + 1);
mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
if (mimeType.isEmpty()) {
mimeType = getPluginMimeTypeFromExtension(extension);
}
}
if (mimeType.isEmpty())
return ObjectContentFrame;
}
if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
return ObjectContentImage;
PluginData* pluginData = m_webFrame->frame()->page()->pluginData();
if (pluginData && pluginData->supportsMimeType(mimeType))
return ObjectContentNetscapePlugin;
if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
return ObjectContentFrame;
return ObjectContentNone;
}
String FrameLoaderClientImpl::overrideMediaType() const
{
return String();
}
bool FrameLoaderClientImpl::actionSpecifiesNavigationPolicy(
const NavigationAction& action,
WebNavigationPolicy* policy)
{
const MouseEvent* event = 0;
if (action.type() == NavigationTypeLinkClicked
&& action.event()->isMouseEvent())
event = static_cast<const MouseEvent*>(action.event());
else if (action.type() == NavigationTypeFormSubmitted
&& action.event()
&& action.event()->underlyingEvent()
&& action.event()->underlyingEvent()->isMouseEvent())
event = static_cast<const MouseEvent*>(action.event()->underlyingEvent());
if (!event)
return false;
return WebViewImpl::navigationPolicyFromMouseEvent(
event->button(), event->ctrlKey(), event->shiftKey(), event->altKey(),
event->metaKey(), policy);
}
PassOwnPtr<WebPluginLoadObserver> FrameLoaderClientImpl::pluginLoadObserver()
{
WebDataSourceImpl* ds = WebDataSourceImpl::fromDocumentLoader(
m_webFrame->frame()->loader()->activeDocumentLoader());
return ds->releasePluginLoadObserver();
}
}