2fafdfe3a8f6e088877dbd518bdf106cd2c1619b
[WebKit.git] / Source / WebKit2 / UIProcess / qt / QtWebPagePolicyClient.cpp
1 /*
2  * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this program; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #include "config.h"
22 #include "QtWebPagePolicyClient.h"
23
24 #include "WKURLQt.h"
25 #include "qquickwebview_p.h"
26 #include "qquickwebview_p_p.h"
27 #include <WKFramePolicyListener.h>
28 #include <WKURLRequest.h>
29
30 QtWebPagePolicyClient::QtWebPagePolicyClient(WKPageRef pageRef, QQuickWebView* webView)
31     : m_webView(webView)
32 {
33     WKPagePolicyClient policyClient;
34     memset(&policyClient, 0, sizeof(WKPagePolicyClient));
35     policyClient.version = kWKPagePolicyClientCurrentVersion;
36     policyClient.clientInfo = this;
37     policyClient.decidePolicyForNavigationAction = decidePolicyForNavigationAction;
38     policyClient.decidePolicyForResponse = decidePolicyForResponse;
39     WKPageSetPagePolicyClient(pageRef, &policyClient);
40 }
41
42 QtWebPagePolicyClient::PolicyAction QtWebPagePolicyClient::decidePolicyForNavigationAction(const QUrl& url, Qt::MouseButton mouseButton, Qt::KeyboardModifiers keyboardModifiers)
43 {
44     return m_webView->d_func()->navigationPolicyForURL(url, mouseButton, keyboardModifiers);
45 }
46
47 static inline QtWebPagePolicyClient* toQtWebPagePolicyClient(const void* clientInfo)
48 {
49     ASSERT(clientInfo);
50     return reinterpret_cast<QtWebPagePolicyClient*>(const_cast<void*>(clientInfo));
51 }
52
53 static Qt::MouseButton toQtMouseButton(WKEventMouseButton button)
54 {
55     switch (button) {
56     case kWKEventMouseButtonLeftButton:
57         return Qt::LeftButton;
58     case kWKEventMouseButtonMiddleButton:
59         return Qt::MiddleButton;
60     case kWKEventMouseButtonRightButton:
61         return Qt::RightButton;
62     case kWKEventMouseButtonNoButton:
63         return Qt::NoButton;
64     }
65     ASSERT_NOT_REACHED();
66     return Qt::NoButton;
67 }
68
69 static Qt::KeyboardModifiers toQtKeyboardModifiers(WKEventModifiers modifiers)
70 {
71     Qt::KeyboardModifiers qtModifiers = Qt::NoModifier;
72     if (modifiers & kWKEventModifiersShiftKey)
73         qtModifiers |= Qt::ShiftModifier;
74     if (modifiers & kWKEventModifiersControlKey)
75         qtModifiers |= Qt::ControlModifier;
76     if (modifiers & kWKEventModifiersAltKey)
77         qtModifiers |= Qt::AltModifier;
78     if (modifiers & kWKEventModifiersMetaKey)
79         qtModifiers |= Qt::MetaModifier;
80     return qtModifiers;
81 }
82
83 void QtWebPagePolicyClient::decidePolicyForNavigationAction(WKPageRef, WKFrameRef, WKFrameNavigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef, const void* clientInfo)
84 {
85     WKURLRef requestURL = WKURLRequestCopyURL(request);
86     QUrl qUrl = WKURLCopyQUrl(requestURL);
87     WKRelease(requestURL);
88
89     PolicyAction action = toQtWebPagePolicyClient(clientInfo)->decidePolicyForNavigationAction(qUrl, toQtMouseButton(mouseButton), toQtKeyboardModifiers(modifiers));
90     switch (action) {
91     case Use:
92         WKFramePolicyListenerUse(listener);
93         return;
94     case Download:
95         WKFramePolicyListenerDownload(listener);
96         return;
97     case Ignore:
98         WKFramePolicyListenerIgnore(listener);
99         return;
100     }
101     ASSERT_NOT_REACHED();
102 }
103
104 void QtWebPagePolicyClient::decidePolicyForResponse(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef, WKFramePolicyListenerRef listener, WKTypeRef, const void*)
105 {
106     String type = toImpl(response)->resourceResponse().mimeType();
107     type.makeLower();
108     bool canShowMIMEType = toImpl(frame)->canShowMIMEType(type);
109
110     if (WKPageGetMainFrame(page) == frame) {
111         if (canShowMIMEType) {
112             WKFramePolicyListenerUse(listener);
113             return;
114         }
115
116         // If we can't use (show) it then we should download it.
117         WKFramePolicyListenerDownload(listener);
118         return;
119     }
120
121     // 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.
122     // It makes the browser intentionally behave differently when it comes to text(application)/xml content in subframes vs. mainframe.
123     if (!canShowMIMEType && !(type == "text/xml" || type == "application/xml")) {
124         WKFramePolicyListenerIgnore(listener);
125         return;
126     }
127
128     WKFramePolicyListenerUse(listener);
129 }
130