[Qt] [WK2] Move PageLoadClient related code to QtWebPageLoadClient
[WebKit.git] / Source / WebKit2 / UIProcess / qt / ClientImpl.cpp
1 /*
2     Copyright (C) 2010 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 library 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 library; 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 #include "config.h"
21 #include "ClientImpl.h"
22
23 #include "WebPageProxy.h"
24 #include "WKAPICast.h"
25 #include "WKURLQt.h"
26 #include <QtPolicyInterface.h>
27 #include <WKArray.h>
28 #include <WKFrame.h>
29 #include <WKFramePolicyListener.h>
30 #include <WKPage.h>
31 #include <WKString.h>
32 #include <WKType.h>
33 #include <WKURLRequest.h>
34
35 using namespace WebKit;
36
37 static inline QtPolicyInterface* toQtPolicyInterface(const void* clientInfo)
38 {
39     ASSERT(clientInfo);
40     return reinterpret_cast<QtPolicyInterface*>(const_cast<void*>(clientInfo));
41 }
42
43 static Qt::MouseButton toQtMouseButton(WKEventMouseButton button)
44 {
45     switch (button) {
46     case kWKEventMouseButtonLeftButton:
47         return Qt::LeftButton;
48     case kWKEventMouseButtonMiddleButton:
49         return Qt::MiddleButton;
50     case kWKEventMouseButtonRightButton:
51         return Qt::RightButton;
52     }
53     return Qt::NoButton;
54 }
55
56 static Qt::KeyboardModifiers toQtKeyboardModifiers(WKEventModifiers modifiers)
57 {
58     Qt::KeyboardModifiers qtModifiers = Qt::NoModifier;
59     if (modifiers & kWKEventModifiersShiftKey)
60         qtModifiers |= Qt::ShiftModifier;
61     if (modifiers & kWKEventModifiersControlKey)
62         qtModifiers |= Qt::ControlModifier;
63     if (modifiers & kWKEventModifiersAltKey)
64         qtModifiers |= Qt::AltModifier;
65     if (modifiers & kWKEventModifiersMetaKey)
66         qtModifiers |= Qt::MetaModifier;
67     return qtModifiers;
68 }
69
70 static void qt_wk_decidePolicyForNavigationAction(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo)
71 {
72     QtPolicyInterface* policyInterface = toQtPolicyInterface(clientInfo);
73     WKURLRef requestURL = WKURLRequestCopyURL(request);
74     QUrl qUrl = WKURLCopyQUrl(requestURL);
75     WKRelease(requestURL);
76
77     QtPolicyInterface::PolicyAction action = policyInterface->navigationPolicyForURL(qUrl, toQtMouseButton(mouseButton), toQtKeyboardModifiers(modifiers));
78     switch (action) {
79     case QtPolicyInterface::Use:
80         WKFramePolicyListenerUse(listener);
81         break;
82     case QtPolicyInterface::Download:
83         WKFramePolicyListenerDownload(listener);
84         break;
85     case QtPolicyInterface::Ignore:
86         WKFramePolicyListenerIgnore(listener);
87         break;
88     }
89 }
90
91 static void qt_wk_decidePolicyForResponse(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo)
92 {
93     String type = toImpl(response)->resourceResponse().mimeType();
94     type.makeLower();
95     bool canShowMIMEType = toImpl(frame)->canShowMIMEType(type);
96
97     if (WKPageGetMainFrame(page) == frame) {
98         if (canShowMIMEType) {
99             WKFramePolicyListenerUse(listener);
100             return;
101         }
102
103         // If we can't use (show) it then we should download it.
104         WKFramePolicyListenerDownload(listener);
105         return;
106     }
107
108     // 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.
109     // It makes the browser intentionally behave differently when it comes to text(application)/xml content in subframes vs. mainframe.
110     if (!canShowMIMEType && !(type == "text/xml" || type == "application/xml")) {
111         WKFramePolicyListenerIgnore(listener);
112         return;
113     }
114
115     WKFramePolicyListenerUse(listener);
116 }
117
118 void qt_wk_didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void*)
119 {
120     if (!WKStringIsEqualToUTF8CString(messageName, "MessageFromNavigatorQtObject"))
121         return;
122
123     ASSERT(messageBody);
124     ASSERT(WKGetTypeID(messageBody) == WKArrayGetTypeID());
125
126     WKArrayRef body = static_cast<WKArrayRef>(messageBody);
127     ASSERT(WKArrayGetSize(body) == 2);
128     ASSERT(WKGetTypeID(WKArrayGetItemAtIndex(body, 0)) == WKPageGetTypeID());
129     ASSERT(WKGetTypeID(WKArrayGetItemAtIndex(body, 1)) == WKStringGetTypeID());
130
131     WKPageRef page = static_cast<WKPageRef>(WKArrayGetItemAtIndex(body, 0));
132     WKStringRef str = static_cast<WKStringRef>(WKArrayGetItemAtIndex(body, 1));
133
134     toImpl(page)->didReceiveMessageFromNavigatorQtObject(toImpl(str)->string());
135 }
136
137 void setupPagePolicyClient(QtPolicyInterface* policyInterface, WebPageProxy* webPageProxy)
138 {
139     WKPagePolicyClient policyClient;
140     memset(&policyClient, 0, sizeof(WKPagePolicyClient));
141     policyClient.version = kWKPagePolicyClientCurrentVersion;
142     policyClient.clientInfo = policyInterface;
143     policyClient.decidePolicyForNavigationAction = qt_wk_decidePolicyForNavigationAction;
144     policyClient.decidePolicyForResponse = qt_wk_decidePolicyForResponse;
145     WKPageSetPagePolicyClient(toAPI(webPageProxy), &policyClient);
146 }
147
148 void setupContextInjectedBundleClient(WKContextRef context)
149 {
150     WKContextInjectedBundleClient injectedBundleClient;
151     memset(&injectedBundleClient, 0, sizeof(WKContextInjectedBundleClient));
152     injectedBundleClient.version = kWKContextInjectedBundleClientCurrentVersion;
153     injectedBundleClient.didReceiveMessageFromInjectedBundle = qt_wk_didReceiveMessageFromInjectedBundle;
154     WKContextSetInjectedBundleClient(context, &injectedBundleClient);
155 }