]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/webview_webkit.cpp
Update documentation about custom schemes and virtual file systems.
[wxWidgets.git] / src / gtk / webview_webkit.cpp
CommitLineData
61b98a2d 1/////////////////////////////////////////////////////////////////////////////
8290e3cd 2// Name: src/gtk/webview_webkit.cpp
61b98a2d
SL
3// Purpose: GTK WebKit backend for web view component
4// Author: Marianne Gagnon, Robert Roebling
5// Id: $Id$
6// Copyright: (c) 2010 Marianne Gagnon, 1998 Robert Roebling
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
ea179539 13#if wxUSE_WEBVIEW_WEBKIT
61b98a2d
SL
14
15#include "wx/stockitem.h"
8290e3cd 16#include "wx/gtk/webview_webkit.h"
61b98a2d
SL
17#include "wx/gtk/control.h"
18#include "wx/gtk/private.h"
f2049b68 19#include "wx/filesys.h"
eea4d01c 20#include "wx/base64.h"
61b98a2d
SL
21#include "webkit/webkit.h"
22
23// ----------------------------------------------------------------------------
24// GTK callbacks
25// ----------------------------------------------------------------------------
26
27extern "C"
28{
29
30static void
d363c7db
SL
31wxgtk_webview_webkit_load_status(GtkWidget* widget,
32 GParamSpec*,
33 wxWebViewWebKit *webKitCtrl)
61b98a2d
SL
34{
35 if (!webKitCtrl->m_ready) return;
36
37 wxString url = webKitCtrl->GetCurrentURL();
38
39 WebKitLoadStatus status;
40 g_object_get(G_OBJECT(widget), "load-status", &status, NULL);
41
42 wxString target; // TODO: get target (if possible)
43
44 if (status == WEBKIT_LOAD_FINISHED)
45 {
46 webKitCtrl->m_busy = false;
47 wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_LOADED,
48 webKitCtrl->GetId(),
49 url, target, false);
50
51 if (webKitCtrl && webKitCtrl->GetEventHandler())
52 webKitCtrl->GetEventHandler()->ProcessEvent(thisEvent);
53 }
54 else if (status == WEBKIT_LOAD_COMMITTED)
55 {
56 webKitCtrl->m_busy = true;
57 wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_NAVIGATED,
58 webKitCtrl->GetId(),
59 url, target, false);
60
61 if (webKitCtrl && webKitCtrl->GetEventHandler())
62 webKitCtrl->GetEventHandler()->ProcessEvent(thisEvent);
63 }
64}
65
780f7262 66static gboolean
36b52591 67wxgtk_webview_webkit_navigation(WebKitWebView *,
780f7262
SL
68 WebKitWebFrame *frame,
69 WebKitNetworkRequest *request,
153530af 70 WebKitWebNavigationAction *,
780f7262
SL
71 WebKitWebPolicyDecision *policy_decision,
72 wxWebViewWebKit *webKitCtrl)
61b98a2d 73{
36b52591
SL
74 if(webKitCtrl->m_guard)
75 {
76 webKitCtrl->m_guard = false;
211da8a5
SL
77 //We set this to make sure that we don't try to load the page again from
78 //the resource request callback
79 webKitCtrl->m_vfsurl = webkit_network_request_get_uri(request);
80 webkit_web_policy_decision_use(policy_decision);
36b52591
SL
81 return FALSE;
82 }
83
61b98a2d
SL
84 webKitCtrl->m_busy = true;
85
86 const gchar* uri = webkit_network_request_get_uri(request);
87
88 wxString target = webkit_web_frame_get_name (frame);
89 wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_NAVIGATING,
90 webKitCtrl->GetId(),
91 wxString( uri, wxConvUTF8 ),
92 target,
93 true);
94
95 if (webKitCtrl && webKitCtrl->GetEventHandler())
96 webKitCtrl->GetEventHandler()->ProcessEvent(thisEvent);
97
98 if (thisEvent.IsVetoed())
99 {
100 webKitCtrl->m_busy = false;
780f7262
SL
101 webkit_web_policy_decision_ignore(policy_decision);
102 return TRUE;
61b98a2d
SL
103 }
104 else
105 {
f2049b68 106 wxString wxuri = uri;
3baf235f
SL
107 wxSharedPtr<wxWebHandler> handler;
108 wxVector<wxSharedPtr<wxWebHandler> > hanlders = webKitCtrl->GetHandlers();
f2049b68 109 //We are not vetoed so see if we match one of the additional handlers
3baf235f 110 for(wxVector<wxSharedPtr<wxWebHandler> >::iterator it = hanlders.begin();
f2049b68
SL
111 it != hanlders.end(); ++it)
112 {
113 if(wxuri.substr(0, (*it)->GetName().length()) == (*it)->GetName())
114 {
115 handler = (*it);
116 }
117 }
118 //If we found a handler we can then use it to load the file directly
119 //ourselves
120 if(handler)
121 {
36b52591 122 webKitCtrl->m_guard = true;
f2049b68 123 wxFSFile* file = handler->GetFile(wxuri);
36b52591
SL
124 if(file)
125 {
126 webKitCtrl->SetPage(*file->GetStream(), wxuri);
127 }
128 //We need to throw some sort of error here if file is NULL
129 webkit_web_policy_decision_ignore(policy_decision);
130 return TRUE;
f2049b68 131 }
780f7262 132 return FALSE;
61b98a2d
SL
133 }
134}
135
136static gboolean
d363c7db
SL
137wxgtk_webview_webkit_error(WebKitWebView*,
138 WebKitWebFrame*,
139 gchar *uri,
140 gpointer web_error,
141 wxWebViewWebKit* webKitWindow)
61b98a2d
SL
142{
143 webKitWindow->m_busy = false;
144 wxWebNavigationError type = wxWEB_NAV_ERR_OTHER;
145
146 GError* error = (GError*)web_error;
147 wxString description(error->message, wxConvUTF8);
148
149 if (strcmp(g_quark_to_string(error->domain), "soup_http_error_quark") == 0)
150 {
151 switch (error->code)
152 {
153 case SOUP_STATUS_CANCELLED:
154 type = wxWEB_NAV_ERR_USER_CANCELLED;
155 break;
156
157 case SOUP_STATUS_CANT_RESOLVE:
158 case SOUP_STATUS_NOT_FOUND:
159 type = wxWEB_NAV_ERR_NOT_FOUND;
160 break;
161
162 case SOUP_STATUS_CANT_RESOLVE_PROXY:
163 case SOUP_STATUS_CANT_CONNECT:
164 case SOUP_STATUS_CANT_CONNECT_PROXY:
165 case SOUP_STATUS_SSL_FAILED:
166 case SOUP_STATUS_IO_ERROR:
167 type = wxWEB_NAV_ERR_CONNECTION;
168 break;
169
170 case SOUP_STATUS_MALFORMED:
171 //case SOUP_STATUS_TOO_MANY_REDIRECTS:
172 type = wxWEB_NAV_ERR_REQUEST;
173 break;
174
175 //case SOUP_STATUS_NO_CONTENT:
176 //case SOUP_STATUS_RESET_CONTENT:
177
178 case SOUP_STATUS_BAD_REQUEST:
179 type = wxWEB_NAV_ERR_REQUEST;
180 break;
181
182 case SOUP_STATUS_UNAUTHORIZED:
183 case SOUP_STATUS_FORBIDDEN:
184 type = wxWEB_NAV_ERR_AUTH;
185 break;
186
187 case SOUP_STATUS_METHOD_NOT_ALLOWED:
188 case SOUP_STATUS_NOT_ACCEPTABLE:
189 type = wxWEB_NAV_ERR_SECURITY;
190 break;
191
192 case SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED:
193 type = wxWEB_NAV_ERR_AUTH;
194 break;
195
196 case SOUP_STATUS_REQUEST_TIMEOUT:
197 type = wxWEB_NAV_ERR_CONNECTION;
198 break;
199
200 //case SOUP_STATUS_PAYMENT_REQUIRED:
201 case SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE:
202 case SOUP_STATUS_REQUEST_URI_TOO_LONG:
203 case SOUP_STATUS_UNSUPPORTED_MEDIA_TYPE:
204 type = wxWEB_NAV_ERR_REQUEST;
205 break;
206
207 case SOUP_STATUS_BAD_GATEWAY:
208 case SOUP_STATUS_SERVICE_UNAVAILABLE:
209 case SOUP_STATUS_GATEWAY_TIMEOUT:
210 type = wxWEB_NAV_ERR_CONNECTION;
211 break;
212
213 case SOUP_STATUS_HTTP_VERSION_NOT_SUPPORTED:
214 type = wxWEB_NAV_ERR_REQUEST;
215 break;
216 //case SOUP_STATUS_INSUFFICIENT_STORAGE:
217 //case SOUP_STATUS_NOT_EXTENDED:
218 }
219 }
220 else if (strcmp(g_quark_to_string(error->domain),
221 "webkit-network-error-quark") == 0)
222 {
223 switch (error->code)
224 {
225 //WEBKIT_NETWORK_ERROR_FAILED:
226 //WEBKIT_NETWORK_ERROR_TRANSPORT:
227
228 case WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL:
229 type = wxWEB_NAV_ERR_REQUEST;
230 break;
231
232 case WEBKIT_NETWORK_ERROR_CANCELLED:
233 type = wxWEB_NAV_ERR_USER_CANCELLED;
234 break;
235
236 case WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST:
237 type = wxWEB_NAV_ERR_NOT_FOUND;
238 break;
239 }
240 }
241 else if (strcmp(g_quark_to_string(error->domain),
242 "webkit-policy-error-quark") == 0)
243 {
244 switch (error->code)
245 {
246 //case WEBKIT_POLICY_ERROR_FAILED:
247 //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE:
248 //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_URL:
249 //case WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE:
250 case WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT:
251 type = wxWEB_NAV_ERR_SECURITY;
252 break;
253 }
254 }
255 /*
256 webkit_plugin_error_quark
257 else
258 {
259 printf("Error domain %s\n", g_quark_to_string(error->domain));
260 }
261 */
262
263 wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_ERROR,
264 webKitWindow->GetId(),
265 uri,
266 wxEmptyString,
267 false);
268 thisEvent.SetString(description);
269 thisEvent.SetInt(type);
270
271 if (webKitWindow && webKitWindow->GetEventHandler())
272 {
273 webKitWindow->GetEventHandler()->ProcessEvent(thisEvent);
274 }
275
276 return FALSE;
277}
278
0016bf1d 279static gboolean
d363c7db
SL
280wxgtk_webview_webkit_new_window(WebKitWebView*,
281 WebKitWebFrame *frame,
282 WebKitNetworkRequest *request,
283 WebKitWebNavigationAction*,
284 WebKitWebPolicyDecision *policy_decision,
285 wxWebViewWebKit *webKitCtrl)
0016bf1d
SL
286{
287 const gchar* uri = webkit_network_request_get_uri(request);
288
289 wxString target = webkit_web_frame_get_name (frame);
290 wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_NEWWINDOW,
291 webKitCtrl->GetId(),
292 wxString( uri, wxConvUTF8 ),
293 target,
294 true);
295
296 if (webKitCtrl && webKitCtrl->GetEventHandler())
297 webKitCtrl->GetEventHandler()->ProcessEvent(thisEvent);
298
75b3bb61
SL
299 //We always want the user to handle this themselves
300 webkit_web_policy_decision_ignore(policy_decision);
0016bf1d
SL
301 return TRUE;
302}
61b98a2d 303
153530af 304static void
bd6f9534
SL
305wxgtk_webview_webkit_title_changed(WebKitWebView*,
306 WebKitWebFrame*,
153530af
SL
307 gchar *title,
308 wxWebViewWebKit *webKitCtrl)
309{
310 wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED,
311 webKitCtrl->GetId(),
312 webKitCtrl->GetCurrentURL(),
313 "",
314 true);
315 thisEvent.SetString(wxString(title, wxConvUTF8));
316
317 if (webKitCtrl && webKitCtrl->GetEventHandler())
318 webKitCtrl->GetEventHandler()->ProcessEvent(thisEvent);
319
320}
321
211da8a5
SL
322static void
323wxgtk_webview_webkit_resource_req(WebKitWebView *,
324 WebKitWebFrame *,
325 WebKitWebResource *,
326 WebKitNetworkRequest *request,
327 WebKitNetworkResponse *,
328 wxWebViewWebKit *webKitCtrl)
329{
330 wxString uri = webkit_network_request_get_uri(request);
331
3baf235f
SL
332 wxSharedPtr<wxWebHandler> handler;
333 wxVector<wxSharedPtr<wxWebHandler> > hanlders = webKitCtrl->GetHandlers();
211da8a5
SL
334
335 //We are not vetoed so see if we match one of the additional handlers
3baf235f 336 for(wxVector<wxSharedPtr<wxWebHandler> >::iterator it = hanlders.begin();
211da8a5
SL
337 it != hanlders.end(); ++it)
338 {
339 if(uri.substr(0, (*it)->GetName().length()) == (*it)->GetName())
340 {
341 handler = (*it);
342 }
343 }
344 //If we found a handler we can then use it to load the file directly
345 //ourselves
346 if(handler)
347 {
348 //If it is requsting the page itself then return as we have already
349 //loaded it from the archive
350 if(webKitCtrl->m_vfsurl == uri)
351 return;
352
353 wxFSFile* file = handler->GetFile(uri);
354 if(file)
355 {
eea4d01c 356 //We load the data into a data url to save it being written out again
211da8a5
SL
357 size_t size = file->GetStream()->GetLength();
358 char *buffer = new char[size];
211da8a5 359 file->GetStream()->Read(buffer, size);
eea4d01c 360 wxString data = wxBase64Encode(buffer, size);
211da8a5 361 delete[] buffer;
eea4d01c
SL
362 wxString mime = file->GetMimeType();
363 wxString path = "data:" + mime + ";base64," + data;
211da8a5 364 //Then we can redirect the call
eea4d01c 365 webkit_network_request_set_uri(request, path);
211da8a5
SL
366 }
367
368 }
369}
370
61b98a2d
SL
371} // extern "C"
372
373//-----------------------------------------------------------------------------
b64b4e70 374// wxWebViewWebKit
61b98a2d
SL
375//-----------------------------------------------------------------------------
376
cddf4541 377wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewWebKit, wxWebView);
61b98a2d 378
b64b4e70 379bool wxWebViewWebKit::Create(wxWindow *parent,
61b98a2d
SL
380 wxWindowID id,
381 const wxString &url,
382 const wxPoint& pos,
383 const wxSize& size,
384 long style,
385 const wxString& name)
386{
387 m_ready = false;
388 m_busy = false;
36b52591 389 m_guard = false;
61b98a2d
SL
390
391 if (!PreCreation( parent, pos, size ) ||
392 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
393 {
b64b4e70 394 wxFAIL_MSG( wxT("wxWebViewWebKit creation failed") );
61b98a2d
SL
395 return false;
396 }
397
398 GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
399 web_view = webkit_web_view_new ();
400 g_object_ref(web_view); // TODO: check memory management
401
402 m_widget = scrolled_window;
403 g_object_ref(m_widget); // TODO: check memory management
404
405 /* Place the WebKitWebView in the GtkScrolledWindow */
406 gtk_container_add (GTK_CONTAINER (scrolled_window), web_view);
407 gtk_widget_show(m_widget);
408 gtk_widget_show(web_view);
409
410 g_signal_connect_after(web_view, "notify::load-status",
d363c7db 411 G_CALLBACK(wxgtk_webview_webkit_load_status),
61b98a2d 412 this);
780f7262
SL
413 g_signal_connect_after(web_view, "navigation-policy-decision-requested",
414 G_CALLBACK(wxgtk_webview_webkit_navigation),
61b98a2d
SL
415 this);
416 g_signal_connect_after(web_view, "load-error",
d363c7db 417 G_CALLBACK(wxgtk_webview_webkit_error),
61b98a2d
SL
418 this);
419
0016bf1d 420 g_signal_connect_after(web_view, "new-window-policy-decision-requested",
d363c7db 421 G_CALLBACK(wxgtk_webview_webkit_new_window), this);
61b98a2d 422
153530af
SL
423 g_signal_connect_after(web_view, "title-changed",
424 G_CALLBACK(wxgtk_webview_webkit_title_changed), this);
425
211da8a5
SL
426 g_signal_connect_after(web_view, "resource-request-starting",
427 G_CALLBACK(wxgtk_webview_webkit_resource_req), this);
428
61b98a2d
SL
429 m_parent->DoAddChild( this );
430
431 PostCreation(size);
432
433 /* Open a webpage */
434 webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), url);
435
152a5808
SL
436 //Get the initial history limit so we can enable and disable it later
437 WebKitWebBackForwardList* history;
438 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
439 m_historyLimit = webkit_web_back_forward_list_get_limit(history);
440
61b98a2d
SL
441 m_ready = true;
442
443 return true;
444}
445
b64b4e70 446bool wxWebViewWebKit::Enable( bool enable )
61b98a2d
SL
447{
448 if (!wxControl::Enable(enable))
449 return false;
450
451 gtk_widget_set_sensitive(GTK_BIN(m_widget)->child, enable);
452
453 //if (enable)
454 // GTKFixSensitivity();
455
456 return true;
457}
458
459GdkWindow*
b64b4e70 460wxWebViewWebKit::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
61b98a2d
SL
461{
462 GdkWindow* window = gtk_widget_get_parent_window(m_widget);
463 return window;
464}
465
b64b4e70 466void wxWebViewWebKit::ZoomIn()
61b98a2d
SL
467{
468 webkit_web_view_zoom_in (WEBKIT_WEB_VIEW(web_view));
469}
470
b64b4e70 471void wxWebViewWebKit::ZoomOut()
61b98a2d
SL
472{
473 webkit_web_view_zoom_out (WEBKIT_WEB_VIEW(web_view));
474}
475
b64b4e70 476void wxWebViewWebKit::SetWebkitZoom(float level)
61b98a2d
SL
477{
478 webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW(web_view), level);
479}
480
b64b4e70 481float wxWebViewWebKit::GetWebkitZoom()
61b98a2d
SL
482{
483 return webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW(web_view));
484}
485
b64b4e70 486void wxWebViewWebKit::Stop()
61b98a2d
SL
487{
488 webkit_web_view_stop_loading (WEBKIT_WEB_VIEW(web_view));
489}
490
b64b4e70 491void wxWebViewWebKit::Reload(wxWebViewReloadFlags flags)
61b98a2d
SL
492{
493 if (flags & wxWEB_VIEW_RELOAD_NO_CACHE)
494 {
495 webkit_web_view_reload_bypass_cache (WEBKIT_WEB_VIEW(web_view));
496 }
497 else
498 {
499 webkit_web_view_reload (WEBKIT_WEB_VIEW(web_view));
500 }
501}
502
b64b4e70 503void wxWebViewWebKit::LoadUrl(const wxString& url)
61b98a2d 504{
b5374b5c 505 webkit_web_view_load_uri(WEBKIT_WEB_VIEW(web_view), wxGTK_CONV(url));
61b98a2d
SL
506}
507
508
b64b4e70 509void wxWebViewWebKit::GoBack()
61b98a2d
SL
510{
511 webkit_web_view_go_back (WEBKIT_WEB_VIEW(web_view));
512}
513
b64b4e70 514void wxWebViewWebKit::GoForward()
61b98a2d
SL
515{
516 webkit_web_view_go_forward (WEBKIT_WEB_VIEW(web_view));
517}
518
519
b64b4e70 520bool wxWebViewWebKit::CanGoBack()
61b98a2d
SL
521{
522 return webkit_web_view_can_go_back (WEBKIT_WEB_VIEW(web_view));
523}
524
525
b64b4e70 526bool wxWebViewWebKit::CanGoForward()
61b98a2d
SL
527{
528 return webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW(web_view));
529}
530
152a5808
SL
531void wxWebViewWebKit::ClearHistory()
532{
533 WebKitWebBackForwardList* history;
534 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
535 webkit_web_back_forward_list_clear(history);
536}
537
538void wxWebViewWebKit::EnableHistory(bool enable)
539{
540 WebKitWebBackForwardList* history;
541 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
542 if(enable)
543 {
544 webkit_web_back_forward_list_set_limit(history, m_historyLimit);
545 }
546 else
547 {
548 webkit_web_back_forward_list_set_limit(history, 0);
549 }
550}
61b98a2d 551
19fc1a2f
SL
552wxVector<wxSharedPtr<wxWebHistoryItem> > wxWebViewWebKit::GetBackwardHistory()
553{
554 wxVector<wxSharedPtr<wxWebHistoryItem> > backhist;
555 WebKitWebBackForwardList* history;
556 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
557 GList* list = webkit_web_back_forward_list_get_back_list_with_limit(history,
558 m_historyLimit);
559 //We need to iterate in reverse to get the order we desire
560 for(int i = g_list_length(list) - 1; i >= 0 ; i--)
561 {
562 WebKitWebHistoryItem* gtkitem = (WebKitWebHistoryItem*)g_list_nth_data(list, i);
263e3a83
SL
563 wxWebHistoryItem* wxitem = new wxWebHistoryItem(
564 webkit_web_history_item_get_uri(gtkitem),
565 webkit_web_history_item_get_title(gtkitem));
566 wxitem->m_histItem = gtkitem;
567 wxSharedPtr<wxWebHistoryItem> item(wxitem);
19fc1a2f 568 backhist.push_back(item);
19fc1a2f
SL
569 }
570 return backhist;
571}
572
573wxVector<wxSharedPtr<wxWebHistoryItem> > wxWebViewWebKit::GetForwardHistory()
574{
575 wxVector<wxSharedPtr<wxWebHistoryItem> > forwardhist;
576 WebKitWebBackForwardList* history;
577 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
578 GList* list = webkit_web_back_forward_list_get_forward_list_with_limit(history,
579 m_historyLimit);
580 for(guint i = 0; i < g_list_length(list); i++)
581 {
582 WebKitWebHistoryItem* gtkitem = (WebKitWebHistoryItem*)g_list_nth_data(list, i);
263e3a83
SL
583 wxWebHistoryItem* wxitem = new wxWebHistoryItem(
584 webkit_web_history_item_get_uri(gtkitem),
585 webkit_web_history_item_get_title(gtkitem));
586 wxitem->m_histItem = gtkitem;
587 wxSharedPtr<wxWebHistoryItem> item(wxitem);
19fc1a2f 588 forwardhist.push_back(item);
19fc1a2f
SL
589 }
590 return forwardhist;
591}
592
593void wxWebViewWebKit::LoadHistoryItem(wxSharedPtr<wxWebHistoryItem> item)
594{
263e3a83 595 WebKitWebHistoryItem* gtkitem = item->m_histItem;
19fc1a2f
SL
596 if(gtkitem)
597 {
598 WebKitWebBackForwardList* history;
599 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
263e3a83
SL
600 webkit_web_back_forward_list_go_to_item(WEBKIT_WEB_BACK_FORWARD_LIST(history),
601 WEBKIT_WEB_HISTORY_ITEM(gtkitem));
19fc1a2f
SL
602 }
603}
604
ae26e17b
SL
605bool wxWebViewWebKit::CanCut()
606{
607 return webkit_web_view_can_cut_clipboard(WEBKIT_WEB_VIEW(web_view));
608}
609
610bool wxWebViewWebKit::CanCopy()
611{
612 return webkit_web_view_can_copy_clipboard(WEBKIT_WEB_VIEW(web_view));
613}
614
615bool wxWebViewWebKit::CanPaste()
616{
617 return webkit_web_view_can_paste_clipboard(WEBKIT_WEB_VIEW(web_view));
618}
619
620void wxWebViewWebKit::Cut()
621{
622 webkit_web_view_cut_clipboard(WEBKIT_WEB_VIEW(web_view));
623}
624
625void wxWebViewWebKit::Copy()
626{
627 webkit_web_view_copy_clipboard(WEBKIT_WEB_VIEW(web_view));
628}
629
630void wxWebViewWebKit::Paste()
631{
632 webkit_web_view_paste_clipboard(WEBKIT_WEB_VIEW(web_view));
633}
634
97e49559
SL
635bool wxWebViewWebKit::CanUndo()
636{
637 return webkit_web_view_can_undo(WEBKIT_WEB_VIEW(web_view));
638}
639
640bool wxWebViewWebKit::CanRedo()
641{
642 return webkit_web_view_can_redo(WEBKIT_WEB_VIEW(web_view));
643}
644
645void wxWebViewWebKit::Undo()
646{
647 webkit_web_view_undo(WEBKIT_WEB_VIEW(web_view));
648}
649
650void wxWebViewWebKit::Redo()
651{
652 webkit_web_view_redo(WEBKIT_WEB_VIEW(web_view));
653}
654
b64b4e70 655wxString wxWebViewWebKit::GetCurrentURL()
61b98a2d
SL
656{
657 // FIXME: check which encoding the web kit control uses instead of
658 // assuming UTF8 (here and elsewhere too)
659 return wxString::FromUTF8(webkit_web_view_get_uri(
660 WEBKIT_WEB_VIEW(web_view)));
661}
662
663
b64b4e70 664wxString wxWebViewWebKit::GetCurrentTitle()
61b98a2d
SL
665{
666 return wxString::FromUTF8(webkit_web_view_get_title(
667 WEBKIT_WEB_VIEW(web_view)));
668}
669
670
b64b4e70 671wxString wxWebViewWebKit::GetPageSource()
61b98a2d
SL
672{
673 WebKitWebFrame* frame = webkit_web_view_get_main_frame(
674 WEBKIT_WEB_VIEW(web_view));
675 WebKitWebDataSource* src = webkit_web_frame_get_data_source (frame);
676
677 // TODO: check encoding with
678 // const gchar*
679 // webkit_web_data_source_get_encoding(WebKitWebDataSource *data_source);
680 return wxString(webkit_web_data_source_get_data (src)->str, wxConvUTF8);
681}
682
683
b64b4e70 684wxWebViewZoom wxWebViewWebKit::GetZoom()
61b98a2d
SL
685{
686 float zoom = GetWebkitZoom();
687
688 // arbitrary way to map float zoom to our common zoom enum
689 if (zoom <= 0.65)
690 {
691 return wxWEB_VIEW_ZOOM_TINY;
692 }
693 else if (zoom > 0.65 && zoom <= 0.90)
694 {
695 return wxWEB_VIEW_ZOOM_SMALL;
696 }
697 else if (zoom > 0.90 && zoom <= 1.15)
698 {
699 return wxWEB_VIEW_ZOOM_MEDIUM;
700 }
701 else if (zoom > 1.15 && zoom <= 1.45)
702 {
703 return wxWEB_VIEW_ZOOM_LARGE;
704 }
705 else if (zoom > 1.45)
706 {
707 return wxWEB_VIEW_ZOOM_LARGEST;
708 }
709
710 // to shut up compilers, this can never be reached logically
711 wxASSERT(false);
712 return wxWEB_VIEW_ZOOM_MEDIUM;
713}
714
715
b64b4e70 716void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom)
61b98a2d
SL
717{
718 // arbitrary way to map our common zoom enum to float zoom
719 switch (zoom)
720 {
721 case wxWEB_VIEW_ZOOM_TINY:
722 SetWebkitZoom(0.6f);
723 break;
724
725 case wxWEB_VIEW_ZOOM_SMALL:
726 SetWebkitZoom(0.8f);
727 break;
728
729 case wxWEB_VIEW_ZOOM_MEDIUM:
730 SetWebkitZoom(1.0f);
731 break;
732
733 case wxWEB_VIEW_ZOOM_LARGE:
734 SetWebkitZoom(1.3);
735 break;
736
737 case wxWEB_VIEW_ZOOM_LARGEST:
738 SetWebkitZoom(1.6);
739 break;
740
741 default:
742 wxASSERT(false);
743 }
744}
745
b64b4e70 746void wxWebViewWebKit::SetZoomType(wxWebViewZoomType type)
61b98a2d
SL
747{
748 webkit_web_view_set_full_content_zoom(WEBKIT_WEB_VIEW(web_view),
749 (type == wxWEB_VIEW_ZOOM_TYPE_LAYOUT ?
750 TRUE : FALSE));
751}
752
b64b4e70 753wxWebViewZoomType wxWebViewWebKit::GetZoomType() const
61b98a2d
SL
754{
755 gboolean fczoom = webkit_web_view_get_full_content_zoom(
756 WEBKIT_WEB_VIEW(web_view));
757
758 if (fczoom) return wxWEB_VIEW_ZOOM_TYPE_LAYOUT;
759 else return wxWEB_VIEW_ZOOM_TYPE_TEXT;
760}
761
b64b4e70 762bool wxWebViewWebKit::CanSetZoomType(wxWebViewZoomType) const
61b98a2d
SL
763{
764 // this port supports all zoom types
765 return true;
766}
767
b64b4e70 768void wxWebViewWebKit::SetPage(const wxString& html, const wxString& baseUri)
61b98a2d
SL
769{
770 webkit_web_view_load_string (WEBKIT_WEB_VIEW(web_view),
771 html.mb_str(wxConvUTF8),
772 "text/html",
773 "UTF-8",
774 baseUri.mb_str(wxConvUTF8));
775}
776
b64b4e70 777void wxWebViewWebKit::Print()
61b98a2d
SL
778{
779 WebKitWebFrame* frame = webkit_web_view_get_main_frame(
780 WEBKIT_WEB_VIEW(web_view));
781 webkit_web_frame_print (frame);
782
783 // GtkPrintOperationResult webkit_web_frame_print_full
784 // (WebKitWebFrame *frame,
785 // GtkPrintOperation *operation,
786 // GtkPrintOperationAction action,
787 // GError **error);
788
789}
790
791
b64b4e70 792bool wxWebViewWebKit::IsBusy()
61b98a2d
SL
793{
794 return m_busy;
795
796 // This code looks nice but returns true after a page was cancelled
797 /*
798 WebKitLoadStatus status = webkit_web_view_get_load_status
799 (WEBKIT_WEB_VIEW(web_view));
800
801
802#if WEBKIT_CHECK_VERSION(1,1,16)
803 // WEBKIT_LOAD_FAILED is new in webkit 1.1.16
804 if (status == WEBKIT_LOAD_FAILED)
805 {
806 return false;
807 }
808#endif
809 if (status == WEBKIT_LOAD_FINISHED)
810 {
811 return false;
812 }
813
814 return true;
815 */
816}
817
c7cbe308
SL
818void wxWebViewWebKit::SetEditable(bool enable)
819{
820 webkit_web_view_set_editable(WEBKIT_WEB_VIEW(web_view), enable);
821}
822
823bool wxWebViewWebKit::IsEditable()
824{
825 return webkit_web_view_get_editable(WEBKIT_WEB_VIEW(web_view));
826}
827
63a65070
SL
828void wxWebViewWebKit::DeleteSelection()
829{
830 webkit_web_view_delete_selection(WEBKIT_WEB_VIEW(web_view));
831}
832
833bool wxWebViewWebKit::HasSelection()
834{
835 return webkit_web_view_has_selection(WEBKIT_WEB_VIEW(web_view));
836}
837
838void wxWebViewWebKit::SelectAll()
839{
840 webkit_web_view_select_all(WEBKIT_WEB_VIEW(web_view));
841}
842
c9355a3d
SL
843wxString wxWebViewWebKit::GetSelectedText()
844{
845 WebKitDOMDocument* doc;
846 WebKitDOMDOMWindow* win;
847 WebKitDOMDOMSelection* sel;
848 WebKitDOMRange* range;
849
850 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view));
851 win = webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc));
852 sel = webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win));
853 range = webkit_dom_dom_selection_get_range_at(WEBKIT_DOM_DOM_SELECTION(sel),
854 0, NULL);
855 return wxString(webkit_dom_range_get_text(WEBKIT_DOM_RANGE(range)),
856 wxConvUTF8);
857}
63a65070 858
97ba4d81 859wxString wxWebViewWebKit::GetSelectedSource()
0fe8a1b6
SL
860{
861 WebKitDOMDocument* doc;
862 WebKitDOMDOMWindow* win;
863 WebKitDOMDOMSelection* sel;
864 WebKitDOMRange* range;
865 WebKitDOMElement* div;
866 WebKitDOMDocumentFragment* clone;
867 WebKitDOMHTMLElement* html;
868
869 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view));
870 win = webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc));
871 sel = webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win));
872 range = webkit_dom_dom_selection_get_range_at(WEBKIT_DOM_DOM_SELECTION(sel),
873 0, NULL);
874 div = webkit_dom_document_create_element(WEBKIT_DOM_DOCUMENT(doc), "div", NULL);
875
876 clone = webkit_dom_range_clone_contents(WEBKIT_DOM_RANGE(range), NULL);
877 webkit_dom_node_append_child(&div->parent_instance, &clone->parent_instance, NULL);
878 html = (WebKitDOMHTMLElement*)div;
879
880 return wxString(webkit_dom_html_element_get_inner_html(WEBKIT_DOM_HTML_ELEMENT(html)),
881 wxConvUTF8);
882}
883
41933aa5
SL
884void wxWebViewWebKit::ClearSelection()
885{
886 WebKitDOMDocument* doc;
887 WebKitDOMDOMWindow* win;
888 WebKitDOMDOMSelection* sel;
889
890 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view));
891 win = webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc));
892 sel = webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win));
893 webkit_dom_dom_selection_remove_all_ranges(WEBKIT_DOM_DOM_SELECTION(sel));
894
895}
896
241b769f
SL
897wxString wxWebViewWebKit::GetPageText()
898{
899 WebKitDOMDocument* doc;
900 WebKitDOMHTMLElement* body;
901
902 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view));
903 body = webkit_dom_document_get_body(WEBKIT_DOM_DOCUMENT(doc));
904 return wxString(webkit_dom_html_element_get_inner_text(WEBKIT_DOM_HTML_ELEMENT(body)),
905 wxConvUTF8);
906}
907
c9ccc09c
SL
908void wxWebViewWebKit::RunScript(const wxString& javascript)
909{
910 webkit_web_view_execute_script(WEBKIT_WEB_VIEW(web_view),
911 javascript.mb_str(wxConvUTF8));
912}
913
3baf235f 914void wxWebViewWebKit::RegisterHandler(wxSharedPtr<wxWebHandler> handler)
f2049b68
SL
915{
916 m_handlerList.push_back(handler);
917}
918
61b98a2d
SL
919// static
920wxVisualAttributes
b64b4e70 921wxWebViewWebKit::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
61b98a2d
SL
922{
923 return GetDefaultAttributesFromGTKWidget(webkit_web_view_new);
924}
925
926
927#endif // wxHAVE_WEB_BACKEND_GTK_WEBKIT