QtWebPagePolicyClient.cpp [plain text]
#include "config.h"
#include "QtWebPagePolicyClient.h"
#include "WKFrame.h"
#include "WKURLQt.h"
#include "qquickwebview_p_p.h"
#include "qwebnavigationrequest_p.h"
#include <QtCore/QObject>
#include <WKFramePolicyListener.h>
#include <WKRetainPtr.h>
#include <WKURLRequest.h>
namespace WebKit {
QtWebPagePolicyClient::QtWebPagePolicyClient(WKPageRef pageRef, QQuickWebView* webView)
: m_webView(webView)
{
WKPagePolicyClient policyClient;
memset(&policyClient, 0, sizeof(WKPagePolicyClient));
policyClient.version = kWKPagePolicyClientCurrentVersion;
policyClient.clientInfo = this;
policyClient.decidePolicyForNavigationAction = decidePolicyForNavigationAction;
policyClient.decidePolicyForResponse = decidePolicyForResponse;
WKPageSetPagePolicyClient(pageRef, &policyClient);
}
void QtWebPagePolicyClient::decidePolicyForNavigationAction(const QUrl& url, Qt::MouseButton mouseButton, Qt::KeyboardModifiers keyboardModifiers, QQuickWebView::NavigationType navigationType, WKFramePolicyListenerRef listener)
{
QWebNavigationRequest navigationRequest(url, mouseButton, keyboardModifiers, navigationType);
emit m_webView->navigationRequested(&navigationRequest);
switch (navigationRequest.action()) {
case QQuickWebView::IgnoreRequest:
WKFramePolicyListenerIgnore(listener);
return;
case QQuickWebViewExperimental::DownloadRequest:
WKFramePolicyListenerDownload(listener);
return;
case QQuickWebView::AcceptRequest:
WKFramePolicyListenerUse(listener);
return;
}
ASSERT_NOT_REACHED();
}
static inline QtWebPagePolicyClient* toQtWebPagePolicyClient(const void* clientInfo)
{
ASSERT(clientInfo);
return reinterpret_cast<QtWebPagePolicyClient*>(const_cast<void*>(clientInfo));
}
static Qt::MouseButton toQtMouseButton(WKEventMouseButton button)
{
switch (button) {
case kWKEventMouseButtonLeftButton:
return Qt::LeftButton;
case kWKEventMouseButtonMiddleButton:
return Qt::MiddleButton;
case kWKEventMouseButtonRightButton:
return Qt::RightButton;
case kWKEventMouseButtonNoButton:
return Qt::NoButton;
}
ASSERT_NOT_REACHED();
return Qt::NoButton;
}
static Qt::KeyboardModifiers toQtKeyboardModifiers(WKEventModifiers modifiers)
{
Qt::KeyboardModifiers qtModifiers = Qt::NoModifier;
if (modifiers & kWKEventModifiersShiftKey)
qtModifiers |= Qt::ShiftModifier;
if (modifiers & kWKEventModifiersControlKey)
qtModifiers |= Qt::ControlModifier;
if (modifiers & kWKEventModifiersAltKey)
qtModifiers |= Qt::AltModifier;
if (modifiers & kWKEventModifiersMetaKey)
qtModifiers |= Qt::MetaModifier;
return qtModifiers;
}
static QQuickWebView::NavigationType toQuickWebViewNavigationType(WKFrameNavigationType navigationType)
{
switch (navigationType) {
case kWKFrameNavigationTypeLinkClicked:
return QQuickWebView::LinkClickedNavigation;
case kWKFrameNavigationTypeFormSubmitted:
return QQuickWebView::FormSubmittedNavigation;
case kWKFrameNavigationTypeBackForward:
return QQuickWebView::BackForwardNavigation;
case kWKFrameNavigationTypeReload:
return QQuickWebView::ReloadNavigation;
case kWKFrameNavigationTypeFormResubmitted:
return QQuickWebView::FormResubmittedNavigation;
case kWKFrameNavigationTypeOther:
return QQuickWebView::OtherNavigation;
}
ASSERT_NOT_REACHED();
return QQuickWebView::OtherNavigation;
}
void QtWebPagePolicyClient::decidePolicyForNavigationAction(WKPageRef, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef, const void* clientInfo)
{
WKRetainPtr<WKURLRef> frameURL(AdoptWK, WKFrameCopyURL(frame));
WKRetainPtr<WKURLRef> requestURL(AdoptWK, WKURLRequestCopyURL(request));
QUrl qUrl = WKURLCopyQUrl(requestURL.get());
toQtWebPagePolicyClient(clientInfo)->decidePolicyForNavigationAction(qUrl, toQtMouseButton(mouseButton), toQtKeyboardModifiers(modifiers), toQuickWebViewNavigationType(navigationType), listener);
}
void QtWebPagePolicyClient::decidePolicyForResponse(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef, WKFramePolicyListenerRef listener, WKTypeRef, const void*)
{
String type = toImpl(response)->resourceResponse().mimeType();
type.makeLower();
bool canShowMIMEType = toImpl(frame)->canShowMIMEType(type);
if (WKPageGetMainFrame(page) == frame) {
if (canShowMIMEType) {
WKFramePolicyListenerUse(listener);
return;
}
WKFramePolicyListenerDownload(listener);
return;
}
if (!canShowMIMEType && !(type == "text/xml" || type == "application/xml")) {
WKFramePolicyListenerIgnore(listener);
return;
}
WKFramePolicyListenerUse(listener);
}
}