Line 0
Link Here
|
|
|
1 |
///////////////////////////////////////////////////////////////////////////// |
2 |
// Name: src/gtk/webview_webkit2.cpp |
3 |
// Purpose: GTK WebKit2 backend for web view component |
4 |
// Author: Scott Talbert |
5 |
// Copyright: (c) 2017 Scott Talbert |
6 |
// Licence: wxWindows licence |
7 |
///////////////////////////////////////////////////////////////////////////// |
8 |
|
9 |
// For compilers that support precompilation, includes "wx.h". |
10 |
#include "wx/wxprec.h" |
11 |
|
12 |
#if wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT2 |
13 |
|
14 |
#include "wx/stockitem.h" |
15 |
#include "wx/gtk/webview_webkit.h" |
16 |
#include "wx/gtk/control.h" |
17 |
#include "wx/gtk/private.h" |
18 |
#include "wx/filesys.h" |
19 |
#include "wx/base64.h" |
20 |
#include "wx/log.h" |
21 |
#include "wx/gtk/private/webview_webkit2_extension.h" |
22 |
#include <webkit2/webkit2.h> |
23 |
|
24 |
// ---------------------------------------------------------------------------- |
25 |
// GTK callbacks |
26 |
// ---------------------------------------------------------------------------- |
27 |
|
28 |
extern "C" |
29 |
{ |
30 |
|
31 |
static void |
32 |
wxgtk_webview_webkit_load_changed(GtkWidget *, |
33 |
WebKitLoadEvent load_event, |
34 |
wxWebViewWebKit *webKitCtrl) |
35 |
{ |
36 |
wxString url = webKitCtrl->GetCurrentURL(); |
37 |
|
38 |
wxString target; // TODO: get target (if possible) |
39 |
|
40 |
if (load_event == WEBKIT_LOAD_FINISHED) |
41 |
{ |
42 |
webKitCtrl->m_busy = false; |
43 |
wxWebViewEvent event(wxEVT_WEBVIEW_LOADED, |
44 |
webKitCtrl->GetId(), |
45 |
url, target); |
46 |
|
47 |
if (webKitCtrl && webKitCtrl->GetEventHandler()) |
48 |
webKitCtrl->GetEventHandler()->ProcessEvent(event); |
49 |
} |
50 |
else if (load_event == WEBKIT_LOAD_COMMITTED) |
51 |
{ |
52 |
webKitCtrl->m_busy = true; |
53 |
wxWebViewEvent event(wxEVT_WEBVIEW_NAVIGATED, |
54 |
webKitCtrl->GetId(), |
55 |
url, target); |
56 |
|
57 |
if (webKitCtrl && webKitCtrl->GetEventHandler()) |
58 |
webKitCtrl->GetEventHandler()->ProcessEvent(event); |
59 |
} |
60 |
} |
61 |
|
62 |
static gboolean |
63 |
wxgtk_webview_webkit_navigation(WebKitWebView *web_view, |
64 |
WebKitPolicyDecision *decision, |
65 |
wxWebViewWebKit *webKitCtrl) |
66 |
{ |
67 |
WebKitNavigationPolicyDecision* navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION(decision); |
68 |
WebKitNavigationAction* action = webkit_navigation_policy_decision_get_navigation_action(navigation_decision); |
69 |
WebKitURIRequest* request = webkit_navigation_action_get_request(action); |
70 |
const gchar* uri = webkit_uri_request_get_uri(request); |
71 |
wxString target = webkit_navigation_policy_decision_get_frame_name(navigation_decision); |
72 |
|
73 |
//If m_creating is true then we are the result of a new window |
74 |
//and so we need to send the event and veto the load |
75 |
if(webKitCtrl->m_creating) |
76 |
{ |
77 |
webKitCtrl->m_creating = false; |
78 |
wxWebViewEvent event(wxEVT_WEBVIEW_NEWWINDOW, |
79 |
webKitCtrl->GetId(), |
80 |
wxString(uri, wxConvUTF8), |
81 |
target); |
82 |
|
83 |
if(webKitCtrl && webKitCtrl->GetEventHandler()) |
84 |
webKitCtrl->GetEventHandler()->ProcessEvent(event); |
85 |
|
86 |
webkit_policy_decision_ignore(decision); |
87 |
return TRUE; |
88 |
} |
89 |
|
90 |
if(webKitCtrl->m_guard) |
91 |
{ |
92 |
webKitCtrl->m_guard = false; |
93 |
//We set this to make sure that we don't try to load the page again from |
94 |
//the resource request callback |
95 |
webKitCtrl->m_vfsurl = webkit_web_view_get_uri(web_view); |
96 |
webkit_policy_decision_use(decision); |
97 |
return FALSE; |
98 |
} |
99 |
|
100 |
webKitCtrl->m_busy = true; |
101 |
|
102 |
wxWebViewEvent event(wxEVT_WEBVIEW_NAVIGATING, |
103 |
webKitCtrl->GetId(), |
104 |
wxString( uri, wxConvUTF8 ), |
105 |
target); |
106 |
|
107 |
if (webKitCtrl && webKitCtrl->GetEventHandler()) |
108 |
webKitCtrl->GetEventHandler()->ProcessEvent(event); |
109 |
|
110 |
if (!event.IsAllowed()) |
111 |
{ |
112 |
webKitCtrl->m_busy = false; |
113 |
webkit_policy_decision_ignore(decision); |
114 |
return TRUE; |
115 |
} |
116 |
else |
117 |
{ |
118 |
wxString wxuri = uri; |
119 |
wxSharedPtr<wxWebViewHandler> handler; |
120 |
wxVector<wxSharedPtr<wxWebViewHandler> > handlers = webKitCtrl->GetHandlers(); |
121 |
//We are not vetoed so see if we match one of the additional handlers |
122 |
for(wxVector<wxSharedPtr<wxWebViewHandler> >::iterator it = handlers.begin(); |
123 |
it != handlers.end(); ++it) |
124 |
{ |
125 |
if(wxuri.substr(0, (*it)->GetName().length()) == (*it)->GetName()) |
126 |
{ |
127 |
handler = (*it); |
128 |
} |
129 |
} |
130 |
//If we found a handler we can then use it to load the file directly |
131 |
//ourselves |
132 |
if(handler) |
133 |
{ |
134 |
webKitCtrl->m_guard = true; |
135 |
wxFSFile* file = handler->GetFile(wxuri); |
136 |
if(file) |
137 |
{ |
138 |
webKitCtrl->SetPage(*file->GetStream(), wxuri); |
139 |
} |
140 |
//We need to throw some sort of error here if file is NULL |
141 |
webkit_policy_decision_ignore(decision); |
142 |
return TRUE; |
143 |
} |
144 |
return FALSE; |
145 |
} |
146 |
} |
147 |
|
148 |
static gboolean |
149 |
wxgtk_webview_webkit_load_failed(WebKitWebView *, |
150 |
WebKitLoadEvent, |
151 |
gchar *uri, |
152 |
GError *error, |
153 |
wxWebViewWebKit* webKitWindow) |
154 |
{ |
155 |
webKitWindow->m_busy = false; |
156 |
wxWebViewNavigationError type = wxWEBVIEW_NAV_ERR_OTHER; |
157 |
|
158 |
wxString description(error->message, wxConvUTF8); |
159 |
|
160 |
if (strcmp(g_quark_to_string(error->domain), "soup_http_error_quark") == 0) |
161 |
{ |
162 |
switch (error->code) |
163 |
{ |
164 |
case SOUP_STATUS_CANCELLED: |
165 |
type = wxWEBVIEW_NAV_ERR_USER_CANCELLED; |
166 |
break; |
167 |
|
168 |
case SOUP_STATUS_CANT_RESOLVE: |
169 |
case SOUP_STATUS_NOT_FOUND: |
170 |
type = wxWEBVIEW_NAV_ERR_NOT_FOUND; |
171 |
break; |
172 |
|
173 |
case SOUP_STATUS_CANT_RESOLVE_PROXY: |
174 |
case SOUP_STATUS_CANT_CONNECT: |
175 |
case SOUP_STATUS_CANT_CONNECT_PROXY: |
176 |
case SOUP_STATUS_SSL_FAILED: |
177 |
case SOUP_STATUS_IO_ERROR: |
178 |
type = wxWEBVIEW_NAV_ERR_CONNECTION; |
179 |
break; |
180 |
|
181 |
case SOUP_STATUS_MALFORMED: |
182 |
type = wxWEBVIEW_NAV_ERR_REQUEST; |
183 |
break; |
184 |
|
185 |
case SOUP_STATUS_BAD_REQUEST: |
186 |
type = wxWEBVIEW_NAV_ERR_REQUEST; |
187 |
break; |
188 |
|
189 |
case SOUP_STATUS_UNAUTHORIZED: |
190 |
case SOUP_STATUS_FORBIDDEN: |
191 |
type = wxWEBVIEW_NAV_ERR_AUTH; |
192 |
break; |
193 |
|
194 |
case SOUP_STATUS_METHOD_NOT_ALLOWED: |
195 |
case SOUP_STATUS_NOT_ACCEPTABLE: |
196 |
type = wxWEBVIEW_NAV_ERR_SECURITY; |
197 |
break; |
198 |
|
199 |
case SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED: |
200 |
type = wxWEBVIEW_NAV_ERR_AUTH; |
201 |
break; |
202 |
|
203 |
case SOUP_STATUS_REQUEST_TIMEOUT: |
204 |
type = wxWEBVIEW_NAV_ERR_CONNECTION; |
205 |
break; |
206 |
|
207 |
case SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE: |
208 |
case SOUP_STATUS_REQUEST_URI_TOO_LONG: |
209 |
case SOUP_STATUS_UNSUPPORTED_MEDIA_TYPE: |
210 |
type = wxWEBVIEW_NAV_ERR_REQUEST; |
211 |
break; |
212 |
|
213 |
case SOUP_STATUS_BAD_GATEWAY: |
214 |
case SOUP_STATUS_SERVICE_UNAVAILABLE: |
215 |
case SOUP_STATUS_GATEWAY_TIMEOUT: |
216 |
type = wxWEBVIEW_NAV_ERR_CONNECTION; |
217 |
break; |
218 |
|
219 |
case SOUP_STATUS_HTTP_VERSION_NOT_SUPPORTED: |
220 |
type = wxWEBVIEW_NAV_ERR_REQUEST; |
221 |
break; |
222 |
} |
223 |
} |
224 |
else if (strcmp(g_quark_to_string(error->domain), |
225 |
"webkit-network-error-quark") == 0) |
226 |
{ |
227 |
switch (error->code) |
228 |
{ |
229 |
case WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL: |
230 |
type = wxWEBVIEW_NAV_ERR_REQUEST; |
231 |
break; |
232 |
|
233 |
case WEBKIT_NETWORK_ERROR_CANCELLED: |
234 |
type = wxWEBVIEW_NAV_ERR_USER_CANCELLED; |
235 |
break; |
236 |
|
237 |
case WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST: |
238 |
type = wxWEBVIEW_NAV_ERR_NOT_FOUND; |
239 |
break; |
240 |
} |
241 |
} |
242 |
else if (strcmp(g_quark_to_string(error->domain), |
243 |
"webkit-policy-error-quark") == 0) |
244 |
{ |
245 |
switch (error->code) |
246 |
{ |
247 |
case WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT: |
248 |
type = wxWEBVIEW_NAV_ERR_SECURITY; |
249 |
break; |
250 |
} |
251 |
} |
252 |
|
253 |
wxWebViewEvent event(wxEVT_WEBVIEW_ERROR, |
254 |
webKitWindow->GetId(), |
255 |
uri, ""); |
256 |
event.SetString(description); |
257 |
event.SetInt(type); |
258 |
|
259 |
if (webKitWindow && webKitWindow->GetEventHandler()) |
260 |
{ |
261 |
webKitWindow->GetEventHandler()->ProcessEvent(event); |
262 |
} |
263 |
|
264 |
return FALSE; |
265 |
} |
266 |
|
267 |
static gboolean |
268 |
wxgtk_webview_webkit_new_window(WebKitPolicyDecision *decision, |
269 |
wxWebViewWebKit *webKitCtrl) |
270 |
{ |
271 |
WebKitNavigationPolicyDecision* navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION(decision); |
272 |
WebKitNavigationAction* action = webkit_navigation_policy_decision_get_navigation_action(navigation_decision); |
273 |
WebKitURIRequest* request = webkit_navigation_action_get_request(action); |
274 |
const gchar* uri = webkit_uri_request_get_uri(request); |
275 |
|
276 |
wxString target = webkit_navigation_policy_decision_get_frame_name(navigation_decision); |
277 |
wxWebViewEvent event(wxEVT_WEBVIEW_NEWWINDOW, |
278 |
webKitCtrl->GetId(), |
279 |
wxString( uri, wxConvUTF8 ), |
280 |
target); |
281 |
|
282 |
if (webKitCtrl && webKitCtrl->GetEventHandler()) |
283 |
webKitCtrl->GetEventHandler()->ProcessEvent(event); |
284 |
|
285 |
//We always want the user to handle this themselves |
286 |
webkit_policy_decision_ignore(decision); |
287 |
return TRUE; |
288 |
} |
289 |
|
290 |
static gboolean |
291 |
wxgtk_webview_webkit_decide_policy(WebKitWebView *web_view, |
292 |
WebKitPolicyDecision *decision, |
293 |
WebKitPolicyDecisionType type, |
294 |
wxWebViewWebKit *webKitCtrl) |
295 |
{ |
296 |
switch (type) |
297 |
{ |
298 |
case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION: |
299 |
return wxgtk_webview_webkit_navigation(web_view, decision, webKitCtrl); |
300 |
case WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION: |
301 |
return wxgtk_webview_webkit_new_window(decision, webKitCtrl); |
302 |
default: |
303 |
return FALSE; |
304 |
} |
305 |
} |
306 |
|
307 |
static void |
308 |
wxgtk_webview_webkit_title_changed(GtkWidget* widget, |
309 |
GParamSpec *, |
310 |
wxWebViewWebKit *webKitCtrl) |
311 |
{ |
312 |
gchar *title; |
313 |
g_object_get(G_OBJECT(widget), "title", &title, NULL); |
314 |
|
315 |
wxWebViewEvent event(wxEVT_WEBVIEW_TITLE_CHANGED, |
316 |
webKitCtrl->GetId(), |
317 |
webKitCtrl->GetCurrentURL(), |
318 |
""); |
319 |
event.SetString(wxString(title, wxConvUTF8)); |
320 |
|
321 |
if (webKitCtrl && webKitCtrl->GetEventHandler()) |
322 |
webKitCtrl->GetEventHandler()->ProcessEvent(event); |
323 |
|
324 |
g_free(title); |
325 |
} |
326 |
|
327 |
static void |
328 |
wxgtk_webview_webkit_resource_req(WebKitWebView *, |
329 |
WebKitWebResource *, |
330 |
WebKitURIRequest *request, |
331 |
wxWebViewWebKit *webKitCtrl) |
332 |
{ |
333 |
wxString uri = webkit_uri_request_get_uri(request); |
334 |
|
335 |
wxSharedPtr<wxWebViewHandler> handler; |
336 |
wxVector<wxSharedPtr<wxWebViewHandler> > handlers = webKitCtrl->GetHandlers(); |
337 |
|
338 |
//We are not vetoed so see if we match one of the additional handlers |
339 |
for(wxVector<wxSharedPtr<wxWebViewHandler> >::iterator it = handlers.begin(); |
340 |
it != handlers.end(); ++it) |
341 |
{ |
342 |
if(uri.substr(0, (*it)->GetName().length()) == (*it)->GetName()) |
343 |
{ |
344 |
handler = (*it); |
345 |
} |
346 |
} |
347 |
//If we found a handler we can then use it to load the file directly |
348 |
//ourselves |
349 |
if(handler) |
350 |
{ |
351 |
//If it is requsting the page itself then return as we have already |
352 |
//loaded it from the archive |
353 |
if(webKitCtrl->m_vfsurl == uri) |
354 |
return; |
355 |
|
356 |
wxFSFile* file = handler->GetFile(uri); |
357 |
if(file) |
358 |
{ |
359 |
//We load the data into a data url to save it being written out again |
360 |
size_t size = file->GetStream()->GetLength(); |
361 |
char *buffer = new char[size]; |
362 |
file->GetStream()->Read(buffer, size); |
363 |
wxString data = wxBase64Encode(buffer, size); |
364 |
delete[] buffer; |
365 |
wxString mime = file->GetMimeType(); |
366 |
wxString path = "data:" + mime + ";base64," + data; |
367 |
//Then we can redirect the call |
368 |
webkit_uri_request_set_uri(request, path.utf8_str()); |
369 |
} |
370 |
|
371 |
} |
372 |
} |
373 |
|
374 |
static gboolean |
375 |
wxgtk_webview_webkit_context_menu(WebKitWebView *, |
376 |
WebKitContextMenu *, |
377 |
GdkEvent *, |
378 |
WebKitHitTestResult *, |
379 |
wxWebViewWebKit *webKitCtrl) |
380 |
{ |
381 |
if(webKitCtrl->IsContextMenuEnabled()) |
382 |
return FALSE; |
383 |
else |
384 |
return TRUE; |
385 |
} |
386 |
|
387 |
static WebKitWebView* |
388 |
wxgtk_webview_webkit_create_webview(WebKitWebView *web_view, |
389 |
WebKitNavigationAction *, |
390 |
wxWebViewWebKit *webKitCtrl) |
391 |
{ |
392 |
//As we do not know the uri being loaded at this point allow the load to |
393 |
//continue and catch it in navigation-policy-decision-requested |
394 |
webKitCtrl->m_creating = true; |
395 |
return web_view; |
396 |
} |
397 |
|
398 |
static void |
399 |
wxgtk_webview_webkit_counted_matches(WebKitFindController *, |
400 |
guint match_count, |
401 |
int *findCount) |
402 |
{ |
403 |
*findCount = match_count; |
404 |
} |
405 |
|
406 |
static void |
407 |
wxgtk_initialize_web_extensions(WebKitWebContext *context, |
408 |
GDBusServer *dbusServer) |
409 |
{ |
410 |
const char *address = g_dbus_server_get_client_address(dbusServer); |
411 |
GVariant *user_data = g_variant_new("(s)", address); |
412 |
webkit_web_context_set_web_extensions_directory(context, |
413 |
WX_WEB_EXTENSIONS_DIRECTORY); |
414 |
webkit_web_context_set_web_extensions_initialization_user_data(context, |
415 |
user_data); |
416 |
} |
417 |
|
418 |
static gboolean |
419 |
wxgtk_new_connection_cb(GDBusServer *, |
420 |
GDBusConnection *connection, |
421 |
GDBusProxy **proxy) |
422 |
{ |
423 |
GError *error = NULL; |
424 |
GDBusProxyFlags flags = static_cast<GDBusProxyFlags>(static_cast<int>(G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES) | static_cast<int>(G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS)); |
425 |
*proxy = g_dbus_proxy_new_sync(connection, |
426 |
flags, |
427 |
NULL, |
428 |
NULL, |
429 |
WXGTK_WEB_EXTENSION_OBJECT_PATH, |
430 |
WXGTK_WEB_EXTENSION_INTERFACE, |
431 |
NULL, |
432 |
&error); |
433 |
if (error) |
434 |
{ |
435 |
g_warning("Failed to create dbus proxy: %s", error->message); |
436 |
g_error_free(error); |
437 |
} |
438 |
|
439 |
return TRUE; |
440 |
} |
441 |
|
442 |
gboolean |
443 |
wxgtk_dbus_peer_is_authorized(GCredentials *peer_credentials) |
444 |
{ |
445 |
static GCredentials *own_credentials = g_credentials_new(); |
446 |
GError *error = NULL; |
447 |
|
448 |
if (peer_credentials && g_credentials_is_same_user(peer_credentials, own_credentials, &error)) |
449 |
{ |
450 |
return TRUE; |
451 |
} |
452 |
|
453 |
if (error) |
454 |
{ |
455 |
g_warning("Failed to authorize web extension connection: %s", error->message); |
456 |
g_error_free(error); |
457 |
} |
458 |
return FALSE; |
459 |
} |
460 |
|
461 |
static gboolean |
462 |
wxgtk_authorize_authenticated_peer_cb(GDBusAuthObserver *, |
463 |
GIOStream *, |
464 |
GCredentials *credentials, |
465 |
wxWebViewWebKit *) |
466 |
{ |
467 |
return wxgtk_dbus_peer_is_authorized(credentials); |
468 |
} |
469 |
|
470 |
} // extern "C" |
471 |
|
472 |
//----------------------------------------------------------------------------- |
473 |
// wxWebViewWebKit |
474 |
//----------------------------------------------------------------------------- |
475 |
|
476 |
wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewWebKit, wxWebView); |
477 |
|
478 |
wxWebViewWebKit::wxWebViewWebKit() |
479 |
{ |
480 |
m_web_view = NULL; |
481 |
m_dbusServer = NULL; |
482 |
m_extension = NULL; |
483 |
} |
484 |
|
485 |
bool wxWebViewWebKit::Create(wxWindow *parent, |
486 |
wxWindowID id, |
487 |
const wxString &url, |
488 |
const wxPoint& pos, |
489 |
const wxSize& size, |
490 |
long style, |
491 |
const wxString& name) |
492 |
{ |
493 |
m_web_view = NULL; |
494 |
m_dbusServer = NULL; |
495 |
m_extension = NULL; |
496 |
m_busy = false; |
497 |
m_guard = false; |
498 |
m_creating = false; |
499 |
FindClear(); |
500 |
|
501 |
// We currently unconditionally impose scrolling in both directions as it's |
502 |
// necessary to show arbitrary pages. |
503 |
style |= wxHSCROLL | wxVSCROLL; |
504 |
|
505 |
if (!PreCreation( parent, pos, size ) || |
506 |
!CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) |
507 |
{ |
508 |
wxFAIL_MSG( wxT("wxWebViewWebKit creation failed") ); |
509 |
return false; |
510 |
} |
511 |
|
512 |
SetupWebExtensionServer(); |
513 |
g_signal_connect_after(webkit_web_context_get_default(), |
514 |
"initialize-web-extensions", |
515 |
G_CALLBACK(wxgtk_initialize_web_extensions), |
516 |
m_dbusServer); |
517 |
|
518 |
m_web_view = WEBKIT_WEB_VIEW(webkit_web_view_new()); |
519 |
GTKCreateScrolledWindowWith(GTK_WIDGET(m_web_view)); |
520 |
g_object_ref(m_widget); |
521 |
|
522 |
g_signal_connect_after(m_web_view, "decide-policy", |
523 |
G_CALLBACK(wxgtk_webview_webkit_decide_policy), |
524 |
this); |
525 |
|
526 |
g_signal_connect_after(m_web_view, "load-failed", |
527 |
G_CALLBACK(wxgtk_webview_webkit_load_failed), this); |
528 |
|
529 |
g_signal_connect_after(m_web_view, "notify::title", |
530 |
G_CALLBACK(wxgtk_webview_webkit_title_changed), this); |
531 |
|
532 |
g_signal_connect_after(m_web_view, "resource-load-started", |
533 |
G_CALLBACK(wxgtk_webview_webkit_resource_req), this); |
534 |
|
535 |
g_signal_connect_after(m_web_view, "context-menu", |
536 |
G_CALLBACK(wxgtk_webview_webkit_context_menu), this); |
537 |
|
538 |
g_signal_connect_after(m_web_view, "create", |
539 |
G_CALLBACK(wxgtk_webview_webkit_create_webview), this); |
540 |
|
541 |
WebKitFindController* findctrl = webkit_web_view_get_find_controller(m_web_view); |
542 |
g_signal_connect_after(findctrl, "counted-matches", |
543 |
G_CALLBACK(wxgtk_webview_webkit_counted_matches), |
544 |
&m_findCount); |
545 |
|
546 |
m_parent->DoAddChild( this ); |
547 |
|
548 |
PostCreation(size); |
549 |
|
550 |
/* Open a webpage */ |
551 |
webkit_web_view_load_uri(m_web_view, url.utf8_str()); |
552 |
|
553 |
// last to avoid getting signal too early |
554 |
g_signal_connect_after(m_web_view, "load-changed", |
555 |
G_CALLBACK(wxgtk_webview_webkit_load_changed), |
556 |
this); |
557 |
|
558 |
return true; |
559 |
} |
560 |
|
561 |
wxWebViewWebKit::~wxWebViewWebKit() |
562 |
{ |
563 |
if (m_web_view) |
564 |
GTKDisconnect(m_web_view); |
565 |
if (m_dbusServer) |
566 |
g_dbus_server_stop(m_dbusServer); |
567 |
g_clear_object(&m_dbusServer); |
568 |
g_clear_object(&m_extension); |
569 |
} |
570 |
|
571 |
bool wxWebViewWebKit::Enable( bool enable ) |
572 |
{ |
573 |
if (!wxControl::Enable(enable)) |
574 |
return false; |
575 |
|
576 |
gtk_widget_set_sensitive(gtk_bin_get_child(GTK_BIN(m_widget)), enable); |
577 |
|
578 |
return true; |
579 |
} |
580 |
|
581 |
GdkWindow* |
582 |
wxWebViewWebKit::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const |
583 |
{ |
584 |
GdkWindow* window = gtk_widget_get_parent_window(m_widget); |
585 |
return window; |
586 |
} |
587 |
|
588 |
void wxWebViewWebKit::ZoomIn() |
589 |
{ |
590 |
SetWebkitZoom(GetWebkitZoom() + 0.1); |
591 |
} |
592 |
|
593 |
void wxWebViewWebKit::ZoomOut() |
594 |
{ |
595 |
SetWebkitZoom(GetWebkitZoom() - 0.1); |
596 |
} |
597 |
|
598 |
void wxWebViewWebKit::SetWebkitZoom(float level) |
599 |
{ |
600 |
webkit_web_view_set_zoom_level(m_web_view, level); |
601 |
} |
602 |
|
603 |
float wxWebViewWebKit::GetWebkitZoom() const |
604 |
{ |
605 |
return webkit_web_view_get_zoom_level(m_web_view); |
606 |
} |
607 |
|
608 |
void wxWebViewWebKit::Stop() |
609 |
{ |
610 |
webkit_web_view_stop_loading(m_web_view); |
611 |
} |
612 |
|
613 |
void wxWebViewWebKit::Reload(wxWebViewReloadFlags flags) |
614 |
{ |
615 |
if (flags & wxWEBVIEW_RELOAD_NO_CACHE) |
616 |
{ |
617 |
webkit_web_view_reload_bypass_cache(m_web_view); |
618 |
} |
619 |
else |
620 |
{ |
621 |
webkit_web_view_reload(m_web_view); |
622 |
} |
623 |
} |
624 |
|
625 |
void wxWebViewWebKit::LoadURL(const wxString& url) |
626 |
{ |
627 |
webkit_web_view_load_uri(m_web_view, wxGTK_CONV(url)); |
628 |
} |
629 |
|
630 |
|
631 |
void wxWebViewWebKit::GoBack() |
632 |
{ |
633 |
webkit_web_view_go_back(m_web_view); |
634 |
} |
635 |
|
636 |
void wxWebViewWebKit::GoForward() |
637 |
{ |
638 |
webkit_web_view_go_forward(m_web_view); |
639 |
} |
640 |
|
641 |
|
642 |
bool wxWebViewWebKit::CanGoBack() const |
643 |
{ |
644 |
return webkit_web_view_can_go_back(m_web_view); |
645 |
} |
646 |
|
647 |
|
648 |
bool wxWebViewWebKit::CanGoForward() const |
649 |
{ |
650 |
return webkit_web_view_can_go_forward(m_web_view); |
651 |
} |
652 |
|
653 |
void wxWebViewWebKit::ClearHistory() |
654 |
{ |
655 |
// In WebKit2GTK+, the BackForwardList can't be cleared so do nothing. |
656 |
} |
657 |
|
658 |
void wxWebViewWebKit::EnableHistory(bool) |
659 |
{ |
660 |
// In WebKit2GTK+, history can't be disabled so do nothing here. |
661 |
} |
662 |
|
663 |
wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewWebKit::GetBackwardHistory() |
664 |
{ |
665 |
wxVector<wxSharedPtr<wxWebViewHistoryItem> > backhist; |
666 |
WebKitBackForwardList* history = |
667 |
webkit_web_view_get_back_forward_list(m_web_view); |
668 |
GList* list = webkit_back_forward_list_get_back_list(history); |
669 |
//We need to iterate in reverse to get the order we desire |
670 |
for(int i = g_list_length(list) - 1; i >= 0 ; i--) |
671 |
{ |
672 |
WebKitBackForwardListItem* gtkitem = (WebKitBackForwardListItem*)g_list_nth_data(list, i); |
673 |
wxWebViewHistoryItem* wxitem = new wxWebViewHistoryItem( |
674 |
webkit_back_forward_list_item_get_uri(gtkitem), |
675 |
webkit_back_forward_list_item_get_title(gtkitem)); |
676 |
wxitem->m_histItem = gtkitem; |
677 |
wxSharedPtr<wxWebViewHistoryItem> item(wxitem); |
678 |
backhist.push_back(item); |
679 |
} |
680 |
return backhist; |
681 |
} |
682 |
|
683 |
wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewWebKit::GetForwardHistory() |
684 |
{ |
685 |
wxVector<wxSharedPtr<wxWebViewHistoryItem> > forwardhist; |
686 |
WebKitBackForwardList* history = |
687 |
webkit_web_view_get_back_forward_list(m_web_view); |
688 |
GList* list = webkit_back_forward_list_get_forward_list(history); |
689 |
for(guint i = 0; i < g_list_length(list); i++) |
690 |
{ |
691 |
WebKitBackForwardListItem* gtkitem = (WebKitBackForwardListItem*)g_list_nth_data(list, i); |
692 |
wxWebViewHistoryItem* wxitem = new wxWebViewHistoryItem( |
693 |
webkit_back_forward_list_item_get_uri(gtkitem), |
694 |
webkit_back_forward_list_item_get_title(gtkitem)); |
695 |
wxitem->m_histItem = gtkitem; |
696 |
wxSharedPtr<wxWebViewHistoryItem> item(wxitem); |
697 |
forwardhist.push_back(item); |
698 |
} |
699 |
return forwardhist; |
700 |
} |
701 |
|
702 |
void wxWebViewWebKit::LoadHistoryItem(wxSharedPtr<wxWebViewHistoryItem> item) |
703 |
{ |
704 |
WebKitBackForwardListItem* gtkitem = (WebKitBackForwardListItem*)item->m_histItem; |
705 |
if(gtkitem) |
706 |
{ |
707 |
webkit_web_view_go_to_back_forward_list_item(m_web_view, |
708 |
WEBKIT_BACK_FORWARD_LIST_ITEM(gtkitem)); |
709 |
} |
710 |
} |
711 |
|
712 |
static void wxgtk_can_execute_editing_command_cb(WebKitWebView *, |
713 |
GAsyncResult *res, |
714 |
GAsyncResult **res_out) |
715 |
{ |
716 |
*res_out = (GAsyncResult*)g_object_ref(res); |
717 |
} |
718 |
|
719 |
bool wxWebViewWebKit::CanExecuteEditingCommand(const gchar* command) const |
720 |
{ |
721 |
GAsyncResult *result = NULL; |
722 |
webkit_web_view_can_execute_editing_command(m_web_view, |
723 |
command, |
724 |
NULL, |
725 |
(GAsyncReadyCallback)wxgtk_can_execute_editing_command_cb, |
726 |
&result); |
727 |
|
728 |
GMainContext *main_context = g_main_context_get_thread_default(); |
729 |
while (!result) |
730 |
{ |
731 |
g_main_context_iteration(main_context, TRUE); |
732 |
} |
733 |
|
734 |
gboolean can_execute = webkit_web_view_can_execute_editing_command_finish(m_web_view, |
735 |
result, |
736 |
NULL); |
737 |
g_object_unref(result); |
738 |
|
739 |
return can_execute; |
740 |
} |
741 |
|
742 |
bool wxWebViewWebKit::CanCut() const |
743 |
{ |
744 |
return CanExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT); |
745 |
} |
746 |
|
747 |
bool wxWebViewWebKit::CanCopy() const |
748 |
{ |
749 |
return CanExecuteEditingCommand(WEBKIT_EDITING_COMMAND_COPY); |
750 |
} |
751 |
|
752 |
bool wxWebViewWebKit::CanPaste() const |
753 |
{ |
754 |
return CanExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE); |
755 |
} |
756 |
|
757 |
void wxWebViewWebKit::Cut() |
758 |
{ |
759 |
webkit_web_view_execute_editing_command(m_web_view, |
760 |
WEBKIT_EDITING_COMMAND_CUT); |
761 |
} |
762 |
|
763 |
void wxWebViewWebKit::Copy() |
764 |
{ |
765 |
webkit_web_view_execute_editing_command(m_web_view, |
766 |
WEBKIT_EDITING_COMMAND_COPY); |
767 |
} |
768 |
|
769 |
void wxWebViewWebKit::Paste() |
770 |
{ |
771 |
webkit_web_view_execute_editing_command(m_web_view, |
772 |
WEBKIT_EDITING_COMMAND_PASTE); |
773 |
} |
774 |
|
775 |
bool wxWebViewWebKit::CanUndo() const |
776 |
{ |
777 |
return CanExecuteEditingCommand(WEBKIT_EDITING_COMMAND_UNDO); |
778 |
} |
779 |
|
780 |
bool wxWebViewWebKit::CanRedo() const |
781 |
{ |
782 |
return CanExecuteEditingCommand(WEBKIT_EDITING_COMMAND_REDO); |
783 |
} |
784 |
|
785 |
void wxWebViewWebKit::Undo() |
786 |
{ |
787 |
webkit_web_view_execute_editing_command(m_web_view, |
788 |
WEBKIT_EDITING_COMMAND_UNDO); |
789 |
} |
790 |
|
791 |
void wxWebViewWebKit::Redo() |
792 |
{ |
793 |
webkit_web_view_execute_editing_command(m_web_view, |
794 |
WEBKIT_EDITING_COMMAND_REDO); |
795 |
} |
796 |
|
797 |
wxString wxWebViewWebKit::GetCurrentURL() const |
798 |
{ |
799 |
// FIXME: check which encoding the web kit control uses instead of |
800 |
// assuming UTF8 (here and elsewhere too) |
801 |
return wxString::FromUTF8(webkit_web_view_get_uri(m_web_view)); |
802 |
} |
803 |
|
804 |
|
805 |
wxString wxWebViewWebKit::GetCurrentTitle() const |
806 |
{ |
807 |
return wxString::FromUTF8(webkit_web_view_get_title(m_web_view)); |
808 |
} |
809 |
|
810 |
|
811 |
static void wxgtk_web_resource_get_data_cb(WebKitWebResource *, |
812 |
GAsyncResult *res, |
813 |
GAsyncResult **res_out) |
814 |
{ |
815 |
*res_out = (GAsyncResult*)g_object_ref(res); |
816 |
} |
817 |
|
818 |
wxString wxWebViewWebKit::GetPageSource() const |
819 |
{ |
820 |
WebKitWebResource *resource = webkit_web_view_get_main_resource(m_web_view); |
821 |
if (!resource) |
822 |
{ |
823 |
return wxString(); |
824 |
} |
825 |
|
826 |
GAsyncResult *result = NULL; |
827 |
webkit_web_resource_get_data(resource, NULL, |
828 |
(GAsyncReadyCallback)wxgtk_web_resource_get_data_cb, |
829 |
&result); |
830 |
|
831 |
GMainContext *main_context = g_main_context_get_thread_default(); |
832 |
while (!result) |
833 |
{ |
834 |
g_main_context_iteration(main_context, TRUE); |
835 |
} |
836 |
|
837 |
guchar *source = webkit_web_resource_get_data_finish(resource, result, |
838 |
NULL, NULL); |
839 |
if (result) |
840 |
{ |
841 |
g_object_unref(result); |
842 |
} |
843 |
|
844 |
if (source) |
845 |
{ |
846 |
wxString wxs = wxString(source, wxConvUTF8); |
847 |
free(source); |
848 |
return wxs; |
849 |
} |
850 |
return wxString(); |
851 |
} |
852 |
|
853 |
|
854 |
wxWebViewZoom wxWebViewWebKit::GetZoom() const |
855 |
{ |
856 |
float zoom = GetWebkitZoom(); |
857 |
|
858 |
// arbitrary way to map float zoom to our common zoom enum |
859 |
if (zoom <= 0.65) |
860 |
{ |
861 |
return wxWEBVIEW_ZOOM_TINY; |
862 |
} |
863 |
else if (zoom > 0.65 && zoom <= 0.90) |
864 |
{ |
865 |
return wxWEBVIEW_ZOOM_SMALL; |
866 |
} |
867 |
else if (zoom > 0.90 && zoom <= 1.15) |
868 |
{ |
869 |
return wxWEBVIEW_ZOOM_MEDIUM; |
870 |
} |
871 |
else if (zoom > 1.15 && zoom <= 1.45) |
872 |
{ |
873 |
return wxWEBVIEW_ZOOM_LARGE; |
874 |
} |
875 |
else if (zoom > 1.45) |
876 |
{ |
877 |
return wxWEBVIEW_ZOOM_LARGEST; |
878 |
} |
879 |
|
880 |
// to shut up compilers, this can never be reached logically |
881 |
wxFAIL; |
882 |
return wxWEBVIEW_ZOOM_MEDIUM; |
883 |
} |
884 |
|
885 |
|
886 |
void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom) |
887 |
{ |
888 |
// arbitrary way to map our common zoom enum to float zoom |
889 |
switch (zoom) |
890 |
{ |
891 |
case wxWEBVIEW_ZOOM_TINY: |
892 |
SetWebkitZoom(0.6f); |
893 |
break; |
894 |
|
895 |
case wxWEBVIEW_ZOOM_SMALL: |
896 |
SetWebkitZoom(0.8f); |
897 |
break; |
898 |
|
899 |
case wxWEBVIEW_ZOOM_MEDIUM: |
900 |
SetWebkitZoom(1.0f); |
901 |
break; |
902 |
|
903 |
case wxWEBVIEW_ZOOM_LARGE: |
904 |
SetWebkitZoom(1.3); |
905 |
break; |
906 |
|
907 |
case wxWEBVIEW_ZOOM_LARGEST: |
908 |
SetWebkitZoom(1.6); |
909 |
break; |
910 |
|
911 |
default: |
912 |
wxFAIL; |
913 |
} |
914 |
} |
915 |
|
916 |
void wxWebViewWebKit::SetZoomType(wxWebViewZoomType type) |
917 |
{ |
918 |
WebKitSettings* settings = webkit_web_view_get_settings(m_web_view); |
919 |
webkit_settings_set_zoom_text_only(settings, |
920 |
(type == wxWEBVIEW_ZOOM_TYPE_TEXT ? |
921 |
TRUE : FALSE)); |
922 |
} |
923 |
|
924 |
wxWebViewZoomType wxWebViewWebKit::GetZoomType() const |
925 |
{ |
926 |
WebKitSettings* settings = webkit_web_view_get_settings(m_web_view); |
927 |
gboolean tozoom = webkit_settings_get_zoom_text_only(settings); |
928 |
|
929 |
if (tozoom) |
930 |
return wxWEBVIEW_ZOOM_TYPE_TEXT; |
931 |
else |
932 |
return wxWEBVIEW_ZOOM_TYPE_LAYOUT; |
933 |
} |
934 |
|
935 |
bool wxWebViewWebKit::CanSetZoomType(wxWebViewZoomType) const |
936 |
{ |
937 |
// this port supports all zoom types |
938 |
return true; |
939 |
} |
940 |
|
941 |
void wxWebViewWebKit::DoSetPage(const wxString& html, const wxString& baseUri) |
942 |
{ |
943 |
webkit_web_view_load_html(m_web_view, |
944 |
html.mb_str(wxConvUTF8), |
945 |
baseUri.mb_str(wxConvUTF8)); |
946 |
} |
947 |
|
948 |
void wxWebViewWebKit::Print() |
949 |
{ |
950 |
WebKitPrintOperation* printop = webkit_print_operation_new(m_web_view); |
951 |
webkit_print_operation_run_dialog(printop, NULL); |
952 |
g_object_unref(printop); |
953 |
} |
954 |
|
955 |
|
956 |
bool wxWebViewWebKit::IsBusy() const |
957 |
{ |
958 |
return m_busy; |
959 |
} |
960 |
|
961 |
void wxWebViewWebKit::SetEditable(bool enable) |
962 |
{ |
963 |
webkit_web_view_set_editable(m_web_view, enable); |
964 |
} |
965 |
|
966 |
bool wxWebViewWebKit::IsEditable() const |
967 |
{ |
968 |
gboolean editable; |
969 |
g_object_get(m_web_view, "editable", &editable, NULL); |
970 |
return editable; |
971 |
} |
972 |
|
973 |
void wxWebViewWebKit::DeleteSelection() |
974 |
{ |
975 |
if (m_extension) |
976 |
{ |
977 |
guint64 page_id = webkit_web_view_get_page_id(m_web_view); |
978 |
GVariant *retval = g_dbus_proxy_call_sync(m_extension, |
979 |
"DeleteSelection", |
980 |
g_variant_new("(t)", page_id), |
981 |
G_DBUS_CALL_FLAGS_NONE, -1, |
982 |
NULL, NULL); |
983 |
if (retval) |
984 |
{ |
985 |
g_variant_unref(retval); |
986 |
} |
987 |
} |
988 |
} |
989 |
|
990 |
bool wxWebViewWebKit::HasSelection() const |
991 |
{ |
992 |
if (m_extension) |
993 |
{ |
994 |
guint64 page_id = webkit_web_view_get_page_id(m_web_view); |
995 |
GVariant *retval = g_dbus_proxy_call_sync(m_extension, |
996 |
"HasSelection", |
997 |
g_variant_new("(t)", page_id), |
998 |
G_DBUS_CALL_FLAGS_NONE, -1, |
999 |
NULL, NULL); |
1000 |
if (retval) |
1001 |
{ |
1002 |
gboolean has_selection = FALSE; |
1003 |
g_variant_get(retval, "(b)", &has_selection); |
1004 |
g_variant_unref(retval); |
1005 |
return has_selection; |
1006 |
} |
1007 |
} |
1008 |
return false; |
1009 |
} |
1010 |
|
1011 |
void wxWebViewWebKit::SelectAll() |
1012 |
{ |
1013 |
webkit_web_view_execute_editing_command(m_web_view, |
1014 |
WEBKIT_EDITING_COMMAND_SELECT_ALL); |
1015 |
} |
1016 |
|
1017 |
wxString wxWebViewWebKit::GetSelectedText() const |
1018 |
{ |
1019 |
if (m_extension) |
1020 |
{ |
1021 |
guint64 page_id = webkit_web_view_get_page_id(m_web_view); |
1022 |
GVariant *retval = g_dbus_proxy_call_sync(m_extension, |
1023 |
"GetSelectedText", |
1024 |
g_variant_new("(t)", page_id), |
1025 |
G_DBUS_CALL_FLAGS_NONE, -1, |
1026 |
NULL, NULL); |
1027 |
if (retval) |
1028 |
{ |
1029 |
char *text; |
1030 |
g_variant_get(retval, "(s)", &text); |
1031 |
g_variant_unref(retval); |
1032 |
return wxString(text, wxConvUTF8); |
1033 |
} |
1034 |
} |
1035 |
return wxString(); |
1036 |
} |
1037 |
|
1038 |
wxString wxWebViewWebKit::GetSelectedSource() const |
1039 |
{ |
1040 |
if (m_extension) |
1041 |
{ |
1042 |
guint64 page_id = webkit_web_view_get_page_id(m_web_view); |
1043 |
GVariant *retval = g_dbus_proxy_call_sync(m_extension, |
1044 |
"GetSelectedSource", |
1045 |
g_variant_new("(t)", page_id), |
1046 |
G_DBUS_CALL_FLAGS_NONE, -1, |
1047 |
NULL, NULL); |
1048 |
if (retval) |
1049 |
{ |
1050 |
char *source; |
1051 |
g_variant_get(retval, "(s)", &source); |
1052 |
g_variant_unref(retval); |
1053 |
return wxString(source, wxConvUTF8); |
1054 |
} |
1055 |
} |
1056 |
return wxString(); |
1057 |
} |
1058 |
|
1059 |
void wxWebViewWebKit::ClearSelection() |
1060 |
{ |
1061 |
if (m_extension) |
1062 |
{ |
1063 |
guint64 page_id = webkit_web_view_get_page_id(m_web_view); |
1064 |
GVariant *retval = g_dbus_proxy_call_sync(m_extension, |
1065 |
"ClearSelection", |
1066 |
g_variant_new("(t)", page_id), |
1067 |
G_DBUS_CALL_FLAGS_NONE, -1, |
1068 |
NULL, NULL); |
1069 |
if (retval) |
1070 |
{ |
1071 |
g_variant_unref(retval); |
1072 |
} |
1073 |
} |
1074 |
} |
1075 |
|
1076 |
wxString wxWebViewWebKit::GetPageText() const |
1077 |
{ |
1078 |
if (m_extension) |
1079 |
{ |
1080 |
guint64 page_id = webkit_web_view_get_page_id(m_web_view); |
1081 |
GVariant *retval = g_dbus_proxy_call_sync(m_extension, |
1082 |
"GetPageText", |
1083 |
g_variant_new("(t)", page_id), |
1084 |
G_DBUS_CALL_FLAGS_NONE, -1, |
1085 |
NULL, NULL); |
1086 |
if (retval) |
1087 |
{ |
1088 |
char *text; |
1089 |
g_variant_get(retval, "(s)", &text); |
1090 |
g_variant_unref(retval); |
1091 |
return wxString(text, wxConvUTF8); |
1092 |
} |
1093 |
} |
1094 |
return wxString(); |
1095 |
} |
1096 |
|
1097 |
void wxWebViewWebKit::RunScript(const wxString& javascript) |
1098 |
{ |
1099 |
webkit_web_view_run_javascript(m_web_view, |
1100 |
javascript.mb_str(wxConvUTF8), |
1101 |
NULL, |
1102 |
NULL, |
1103 |
NULL); |
1104 |
} |
1105 |
|
1106 |
void wxWebViewWebKit::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) |
1107 |
{ |
1108 |
m_handlerList.push_back(handler); |
1109 |
} |
1110 |
|
1111 |
void wxWebViewWebKit::EnableContextMenu(bool enable) |
1112 |
{ |
1113 |
wxWebView::EnableContextMenu(enable); |
1114 |
} |
1115 |
|
1116 |
long wxWebViewWebKit::Find(const wxString& text, int flags) |
1117 |
{ |
1118 |
WebKitFindController* findctrl = webkit_web_view_get_find_controller(m_web_view); |
1119 |
bool newSearch = false; |
1120 |
if(text != m_findText || |
1121 |
(flags & wxWEBVIEW_FIND_MATCH_CASE) != (m_findFlags & wxWEBVIEW_FIND_MATCH_CASE)) |
1122 |
{ |
1123 |
newSearch = true; |
1124 |
//If it is a new search we need to clear existing highlights |
1125 |
webkit_find_controller_search_finish(findctrl); |
1126 |
} |
1127 |
|
1128 |
m_findFlags = flags; |
1129 |
m_findText = text; |
1130 |
|
1131 |
//If the search string is empty then we clear any selection and highlight |
1132 |
if(text.empty()) |
1133 |
{ |
1134 |
webkit_find_controller_search_finish(findctrl); |
1135 |
ClearSelection(); |
1136 |
return wxNOT_FOUND; |
1137 |
} |
1138 |
|
1139 |
bool wrap = false, forward = true; |
1140 |
guint32 options = WEBKIT_FIND_OPTIONS_NONE; |
1141 |
if(flags & wxWEBVIEW_FIND_WRAP) |
1142 |
{ |
1143 |
wrap = true; |
1144 |
options |= WEBKIT_FIND_OPTIONS_WRAP_AROUND; |
1145 |
} |
1146 |
if(!(flags & wxWEBVIEW_FIND_MATCH_CASE)) |
1147 |
{ |
1148 |
options |= WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE; |
1149 |
} |
1150 |
if(flags & wxWEBVIEW_FIND_BACKWARDS) |
1151 |
{ |
1152 |
forward = false; |
1153 |
options |= WEBKIT_FIND_OPTIONS_BACKWARDS; |
1154 |
} |
1155 |
|
1156 |
if(newSearch) |
1157 |
{ |
1158 |
//Initially we count the matches to know how many we have |
1159 |
m_findCount = -1; |
1160 |
webkit_find_controller_count_matches(findctrl, |
1161 |
wxGTK_CONV(text), |
1162 |
options, |
1163 |
G_MAXUINT); |
1164 |
GMainContext *main_context = g_main_context_get_thread_default(); |
1165 |
while (m_findCount == -1) |
1166 |
{ |
1167 |
g_main_context_iteration(main_context, TRUE); |
1168 |
} |
1169 |
//Highlight them if needed |
1170 |
if(flags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT) |
1171 |
{ |
1172 |
webkit_find_controller_search(findctrl, |
1173 |
wxGTK_CONV(text), |
1174 |
options, |
1175 |
G_MAXUINT); |
1176 |
} |
1177 |
//In this case we return early to match IE behaviour |
1178 |
m_findPosition = -1; |
1179 |
return m_findCount; |
1180 |
} |
1181 |
else |
1182 |
{ |
1183 |
if(forward) |
1184 |
m_findPosition++; |
1185 |
else |
1186 |
m_findPosition--; |
1187 |
if(m_findPosition < 0) |
1188 |
m_findPosition += m_findCount; |
1189 |
if(m_findPosition > m_findCount) |
1190 |
m_findPosition -= m_findCount; |
1191 |
} |
1192 |
|
1193 |
if(forward) |
1194 |
{ |
1195 |
webkit_find_controller_search_next(findctrl); |
1196 |
if(m_findPosition == m_findCount && !wrap) |
1197 |
{ |
1198 |
return wxNOT_FOUND; |
1199 |
} |
1200 |
} |
1201 |
else |
1202 |
{ |
1203 |
webkit_find_controller_search_previous(findctrl); |
1204 |
if(m_findPosition == -1 && !wrap) |
1205 |
{ |
1206 |
return wxNOT_FOUND; |
1207 |
} |
1208 |
} |
1209 |
|
1210 |
return newSearch ? m_findCount : m_findPosition; |
1211 |
} |
1212 |
|
1213 |
void wxWebViewWebKit::FindClear() |
1214 |
{ |
1215 |
m_findCount = 0; |
1216 |
m_findFlags = 0; |
1217 |
m_findText.clear(); |
1218 |
m_findPosition = -1; |
1219 |
} |
1220 |
|
1221 |
// static |
1222 |
wxVisualAttributes |
1223 |
wxWebViewWebKit::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant)) |
1224 |
{ |
1225 |
return GetDefaultAttributesFromGTKWidget(webkit_web_view_new()); |
1226 |
} |
1227 |
|
1228 |
void wxWebViewWebKit::SetupWebExtensionServer() |
1229 |
{ |
1230 |
char *address = g_strdup_printf("unix:tmpdir=%s", g_get_tmp_dir()); |
1231 |
char *guid = g_dbus_generate_guid(); |
1232 |
GDBusAuthObserver *observer = g_dbus_auth_observer_new(); |
1233 |
GError *error = NULL; |
1234 |
|
1235 |
g_signal_connect(observer, "authorize-authenticated-peer", |
1236 |
G_CALLBACK(wxgtk_authorize_authenticated_peer_cb), this); |
1237 |
|
1238 |
m_dbusServer = g_dbus_server_new_sync(address, |
1239 |
G_DBUS_SERVER_FLAGS_NONE, |
1240 |
guid, |
1241 |
observer, |
1242 |
NULL, |
1243 |
&error); |
1244 |
|
1245 |
if (error) |
1246 |
{ |
1247 |
g_warning("Failed to start web extension server on %s: %s", address, error->message); |
1248 |
g_error_free(error); |
1249 |
} |
1250 |
else |
1251 |
{ |
1252 |
g_signal_connect(m_dbusServer, "new-connection", |
1253 |
G_CALLBACK(wxgtk_new_connection_cb), &m_extension); |
1254 |
g_dbus_server_start(m_dbusServer); |
1255 |
} |
1256 |
|
1257 |
g_free(address); |
1258 |
g_free(guid); |
1259 |
g_object_unref(observer); |
1260 |
} |
1261 |
|
1262 |
#endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT2 |