diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp')
-rw-r--r-- | Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp b/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp new file mode 100644 index 000000000..e77fb1463 --- /dev/null +++ b/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "QtWebPagePolicyClient.h" + +#include "WKFrame.h" +#include "WKURLQt.h" +#include "qquickwebview_p.h" +#include "qquickwebview_p_p.h" +#include "qwebnavigationrequest_p.h" +#include <QtCore/QObject> +#include <WKFramePolicyListener.h> +#include <WKURLRequest.h> + +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, const QUrl& originatingUrl, Qt::MouseButton mouseButton, Qt::KeyboardModifiers keyboardModifiers, WKFramePolicyListenerRef listener) +{ + // NOTE: even though the C API (and the WebKit2 IPC) supports an asynchronous answer, this is not currently working. + // We are expected to call the listener immediately. See the patch for https://bugs.webkit.org/show_bug.cgi?id=53785. + QWebNavigationRequest navigationRequest(url, originatingUrl, mouseButton, keyboardModifiers); + 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; +} + +void QtWebPagePolicyClient::decidePolicyForNavigationAction(WKPageRef, WKFrameRef frame, WKFrameNavigationType, 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 qUrlFrame = WKURLCopyQUrl(frameURL.get()); + QUrl qUrl = WKURLCopyQUrl(requestURL.get()); + toQtWebPagePolicyClient(clientInfo)->decidePolicyForNavigationAction(qUrl, qUrlFrame, toQtMouseButton(mouseButton), toQtKeyboardModifiers(modifiers), 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; + } + + // If we can't use (show) it then we should download it. + WKFramePolicyListenerDownload(listener); + return; + } + + // We should ignore downloadable top-level content for subframes, with an exception for text/xml and application/xml so we can still support Acid3 test. + // It makes the browser intentionally behave differently when it comes to text(application)/xml content in subframes vs. mainframe. + if (!canShowMIMEType && !(type == "text/xml" || type == "application/xml")) { + WKFramePolicyListenerIgnore(listener); + return; + } + + WKFramePolicyListenerUse(listener); +} |