341ed0746595e93dbf4d64c0b51a8441c03f3bdc
[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 "WebFrameProxy.h"
24 #include "WKAPICast.h"
25 #include "WKStringQt.h"
26 #include "WKURLQt.h"
27 #include "qweberror.h"
28 #include "qweberror_p.h"
29 #include <PolicyInterface.h>
30 #include <QtWebPageProxy.h>
31 #include <ViewInterface.h>
32 #include <WKArray.h>
33 #include <WKFrame.h>
34 #include <WKFramePolicyListener.h>
35 #include <WKHitTestResult.h>
36 #include <WKOpenPanelParameters.h>
37 #include <WKOpenPanelResultListener.h>
38 #include <WKType.h>
39 #include <WKURLRequest.h>
40
41 using namespace WebKit;
42
43 static QtWebPageProxy* toQtWebPageProxy(const void* clientInfo)
44 {
45     if (clientInfo)
46         return reinterpret_cast<QtWebPageProxy*>(const_cast<void*>(clientInfo));
47     return 0;
48 }
49
50 static inline ViewInterface* toViewInterface(const void* clientInfo)
51 {
52     ASSERT(clientInfo);
53     return reinterpret_cast<ViewInterface*>(const_cast<void*>(clientInfo));
54 }
55
56 static inline PolicyInterface* toPolicyInterface(const void* clientInfo)
57 {
58     ASSERT(clientInfo);
59     return reinterpret_cast<PolicyInterface*>(const_cast<void*>(clientInfo));
60 }
61
62 static void dispatchLoadSucceeded(WKFrameRef frame, const void* clientInfo)
63 {
64     if (!WKFrameIsMainFrame(frame))
65         return;
66
67     toQtWebPageProxy(clientInfo)->updateNavigationActions();
68     toQtWebPageProxy(clientInfo)->loadDidSucceed();
69 }
70
71 static void dispatchLoadFailed(WKFrameRef frame, const void* clientInfo, WKErrorRef error)
72 {
73     if (!WKFrameIsMainFrame(frame))
74         return;
75
76     toQtWebPageProxy(clientInfo)->updateNavigationActions();
77
78     int errorCode = WKErrorGetErrorCode(error);
79     if (toImpl(error)->platformError().isCancellation() || errorCode == kWKErrorCodeFrameLoadInterruptedByPolicyChange || errorCode == kWKErrorCodePlugInWillHandleLoad)
80         return;
81
82     toQtWebPageProxy(clientInfo)->loadDidFail(QWebErrorPrivate::createQWebError(error));
83 }
84
85 void qt_wk_didStartProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo)
86 {
87     if (!WKFrameIsMainFrame(frame))
88         return;
89
90     toQtWebPageProxy(clientInfo)->updateNavigationActions();
91     toQtWebPageProxy(clientInfo)->loadDidBegin();
92 }
93
94 void qt_wk_didFailProvisionalLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, WKErrorRef error, WKTypeRef userData, const void* clientInfo)
95 {
96     dispatchLoadFailed(frame, clientInfo, error);
97 }
98
99 void qt_wk_didCommitLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo)
100 {
101     if (!WKFrameIsMainFrame(frame))
102         return;
103     WebFrameProxy* wkframe = toImpl(frame);
104     QString urlStr(wkframe->url());
105     QUrl qUrl = urlStr;
106     toQtWebPageProxy(clientInfo)->updateNavigationActions();
107     toQtWebPageProxy(clientInfo)->didChangeUrl(qUrl);
108     toQtWebPageProxy(clientInfo)->loadDidCommit();
109 }
110
111 void qt_wk_didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo)
112 {
113     dispatchLoadSucceeded(frame, clientInfo);
114 }
115
116 void qt_wk_didFailLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, WKErrorRef error, WKTypeRef userData, const void* clientInfo)
117 {
118     dispatchLoadFailed(frame, clientInfo, error);
119 }
120
121 void qt_wk_didSameDocumentNavigationForFrame(WKPageRef page, WKFrameRef frame, WKSameDocumentNavigationType type, WKTypeRef userData, const void* clientInfo)
122 {
123     WebFrameProxy* wkframe = toImpl(frame);
124     QString urlStr(wkframe->url());
125     QUrl qUrl = urlStr;
126     toQtWebPageProxy(clientInfo)->updateNavigationActions();
127     toQtWebPageProxy(clientInfo)->didChangeUrl(qUrl);
128 }
129
130 void qt_wk_didReceiveTitleForFrame(WKPageRef page, WKStringRef title, WKFrameRef frame, WKTypeRef userData, const void* clientInfo)
131 {
132     if (!WKFrameIsMainFrame(frame))
133         return;
134     QString qTitle = WKStringCopyQString(title);
135     toQtWebPageProxy(clientInfo)->didChangeTitle(qTitle);
136 }
137
138 void qt_wk_didStartProgress(WKPageRef page, const void* clientInfo)
139 {
140     toQtWebPageProxy(clientInfo)->didChangeLoadProgress(0);
141 }
142
143 void qt_wk_didChangeProgress(WKPageRef page, const void* clientInfo)
144 {
145     toQtWebPageProxy(clientInfo)->didChangeLoadProgress(WKPageGetEstimatedProgress(page) * 100);
146 }
147
148 void qt_wk_didFinishProgress(WKPageRef page, const void* clientInfo)
149 {
150     toQtWebPageProxy(clientInfo)->didChangeLoadProgress(100);
151 }
152
153 void qt_wk_runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void* clientInfo)
154 {
155     QString qAlertText = WKStringCopyQString(alertText);
156     toViewInterface(clientInfo)->runJavaScriptAlert(qAlertText);
157 }
158
159 bool qt_wk_runJavaScriptConfirm(WKPageRef, WKStringRef message, WKFrameRef, const void* clientInfo)
160 {
161     QString qMessage = WKStringCopyQString(message);
162     return toViewInterface(clientInfo)->runJavaScriptConfirm(qMessage);
163 }
164
165 static inline WKStringRef createNullWKString()
166 {
167     RefPtr<WebString> webString = WebString::createNull();
168     return toAPI(webString.release().leakRef());
169 }
170
171 WKStringRef qt_wk_runJavaScriptPrompt(WKPageRef, WKStringRef message, WKStringRef defaultValue, WKFrameRef, const void* clientInfo)
172 {
173     QString qMessage = WKStringCopyQString(message);
174     QString qDefaultValue = WKStringCopyQString(defaultValue);
175     bool ok = false;
176     QString result = toViewInterface(clientInfo)->runJavaScriptPrompt(qMessage, qDefaultValue, ok);
177     if (!ok)
178         return createNullWKString();
179     return WKStringCreateWithQString(result);
180 }
181
182 void qt_wk_setStatusText(WKPageRef, WKStringRef text, const void *clientInfo)
183 {
184     QString qText = WKStringCopyQString(text);
185     toViewInterface(clientInfo)->didChangeStatusText(qText);
186 }
187
188 void qt_wk_runOpenPanel(WKPageRef, WKFrameRef, WKOpenPanelParametersRef parameters, WKOpenPanelResultListenerRef listener, const void* clientInfo)
189 {
190     Vector<String> wkSelectedFileNames = toImpl(parameters)->selectedFileNames();
191
192     QStringList selectedFileNames;
193     if (!wkSelectedFileNames.isEmpty())
194         for (unsigned i = 0; wkSelectedFileNames.size(); ++i)
195             selectedFileNames += wkSelectedFileNames.at(i);
196
197     ViewInterface::FileChooserType allowMultipleFiles = WKOpenPanelParametersGetAllowsMultipleFiles(parameters) ? ViewInterface::MultipleFilesSelection : ViewInterface::SingleFileSelection;
198     toViewInterface(clientInfo)->chooseFiles(listener, selectedFileNames, allowMultipleFiles);
199 }
200
201 void qt_wk_mouseDidMoveOverElement(WKPageRef page, WKHitTestResultRef hitTestResult, WKEventModifiers modifiers, WKTypeRef userData, const void* clientInfo)
202 {
203     const QUrl absoluteLinkUrl = WKURLCopyQUrl(WKHitTestResultCopyAbsoluteLinkURL(hitTestResult));
204     const QString linkTitle = WKStringCopyQString(WKHitTestResultCopyLinkTitle(hitTestResult));
205     toViewInterface(clientInfo)->didMouseMoveOverElement(absoluteLinkUrl, linkTitle);
206 }
207
208 static Qt::MouseButton toQtMouseButton(WKEventMouseButton button)
209 {
210     switch (button) {
211     case kWKEventMouseButtonLeftButton:
212         return Qt::LeftButton;
213     case kWKEventMouseButtonMiddleButton:
214         return Qt::MiddleButton;
215     case kWKEventMouseButtonRightButton:
216         return Qt::RightButton;
217     }
218     return Qt::NoButton;
219 }
220
221 static Qt::KeyboardModifiers toQtKeyboardModifiers(WKEventModifiers modifiers)
222 {
223     Qt::KeyboardModifiers qtModifiers = Qt::NoModifier;
224     if (modifiers & kWKEventModifiersShiftKey)
225         qtModifiers |= Qt::ShiftModifier;
226     if (modifiers & kWKEventModifiersControlKey)
227         qtModifiers |= Qt::ControlModifier;
228     if (modifiers & kWKEventModifiersAltKey)
229         qtModifiers |= Qt::AltModifier;
230     if (modifiers & kWKEventModifiersMetaKey)
231         qtModifiers |= Qt::MetaModifier;
232     return qtModifiers;
233 }
234
235 void qt_wk_decidePolicyForNavigationAction(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo)
236 {
237     PolicyInterface* policyInterface = toPolicyInterface(clientInfo);
238     WKURLRef requestURL = WKURLRequestCopyURL(request);
239     QUrl qUrl = WKURLCopyQUrl(requestURL);
240     WKRelease(requestURL);
241
242     PolicyInterface::PolicyAction action = policyInterface->navigationPolicyForURL(qUrl, toQtMouseButton(mouseButton), toQtKeyboardModifiers(modifiers));
243     switch (action) {
244     case PolicyInterface::Use:
245         WKFramePolicyListenerUse(listener);
246         break;
247     case PolicyInterface::Download:
248         WKFramePolicyListenerDownload(listener);
249         break;
250     case PolicyInterface::Ignore:
251         WKFramePolicyListenerIgnore(listener);
252         break;
253     }
254 }