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