Rename wxWebNavigationError to wxWebViewNavigationError and wxWebNavigationEvent...
[wxWidgets.git] / src / gtk / webview_webkit.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/webview_webkit.cpp
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
13 #if wxUSE_WEBVIEW_WEBKIT
14
15 #include "wx/stockitem.h"
16 #include "wx/gtk/webview_webkit.h"
17 #include "wx/gtk/control.h"
18 #include "wx/gtk/private.h"
19 #include "wx/filesys.h"
20 #include "wx/base64.h"
21 #include "webkit/webkit.h"
22
23 // ----------------------------------------------------------------------------
24 // GTK callbacks
25 // ----------------------------------------------------------------------------
26
27 extern "C"
28 {
29
30 static void
31 wxgtk_webview_webkit_load_status(GtkWidget* widget,
32 GParamSpec*,
33 wxWebViewWebKit *webKitCtrl)
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 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_LOADED,
48 webKitCtrl->GetId(),
49 url, target, false);
50
51 if (webKitCtrl && webKitCtrl->GetEventHandler())
52 webKitCtrl->GetEventHandler()->ProcessEvent(event);
53 }
54 else if (status == WEBKIT_LOAD_COMMITTED)
55 {
56 webKitCtrl->m_busy = true;
57 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED,
58 webKitCtrl->GetId(),
59 url, target, false);
60
61 if (webKitCtrl && webKitCtrl->GetEventHandler())
62 webKitCtrl->GetEventHandler()->ProcessEvent(event);
63 }
64 }
65
66 static gboolean
67 wxgtk_webview_webkit_navigation(WebKitWebView *,
68 WebKitWebFrame *frame,
69 WebKitNetworkRequest *request,
70 WebKitWebNavigationAction *,
71 WebKitWebPolicyDecision *policy_decision,
72 wxWebViewWebKit *webKitCtrl)
73 {
74 if(webKitCtrl->m_guard)
75 {
76 webKitCtrl->m_guard = false;
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);
81 return FALSE;
82 }
83
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 wxWebViewEvent event(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(event);
97
98 if (event.IsVetoed())
99 {
100 webKitCtrl->m_busy = false;
101 webkit_web_policy_decision_ignore(policy_decision);
102 return TRUE;
103 }
104 else
105 {
106 wxString wxuri = uri;
107 wxSharedPtr<wxWebViewHandler> handler;
108 wxVector<wxSharedPtr<wxWebViewHandler> > hanlders = webKitCtrl->GetHandlers();
109 //We are not vetoed so see if we match one of the additional handlers
110 for(wxVector<wxSharedPtr<wxWebViewHandler> >::iterator it = hanlders.begin();
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 {
122 webKitCtrl->m_guard = true;
123 wxFSFile* file = handler->GetFile(wxuri);
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;
131 }
132 return FALSE;
133 }
134 }
135
136 static gboolean
137 wxgtk_webview_webkit_error(WebKitWebView*,
138 WebKitWebFrame*,
139 gchar *uri,
140 gpointer web_error,
141 wxWebViewWebKit* webKitWindow)
142 {
143 webKitWindow->m_busy = false;
144 wxWebViewNavigationError 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 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_ERROR,
264 webKitWindow->GetId(),
265 uri, "", false);
266 event.SetString(description);
267 event.SetInt(type);
268
269 if (webKitWindow && webKitWindow->GetEventHandler())
270 {
271 webKitWindow->GetEventHandler()->ProcessEvent(event);
272 }
273
274 return FALSE;
275 }
276
277 static gboolean
278 wxgtk_webview_webkit_new_window(WebKitWebView*,
279 WebKitWebFrame *frame,
280 WebKitNetworkRequest *request,
281 WebKitWebNavigationAction*,
282 WebKitWebPolicyDecision *policy_decision,
283 wxWebViewWebKit *webKitCtrl)
284 {
285 const gchar* uri = webkit_network_request_get_uri(request);
286
287 wxString target = webkit_web_frame_get_name (frame);
288 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NEWWINDOW,
289 webKitCtrl->GetId(),
290 wxString( uri, wxConvUTF8 ),
291 target,
292 true);
293
294 if (webKitCtrl && webKitCtrl->GetEventHandler())
295 webKitCtrl->GetEventHandler()->ProcessEvent(event);
296
297 //We always want the user to handle this themselves
298 webkit_web_policy_decision_ignore(policy_decision);
299 return TRUE;
300 }
301
302 static void
303 wxgtk_webview_webkit_title_changed(WebKitWebView*,
304 WebKitWebFrame*,
305 gchar *title,
306 wxWebViewWebKit *webKitCtrl)
307 {
308 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED,
309 webKitCtrl->GetId(),
310 webKitCtrl->GetCurrentURL(),
311 "", true);
312 event.SetString(wxString(title, wxConvUTF8));
313
314 if (webKitCtrl && webKitCtrl->GetEventHandler())
315 webKitCtrl->GetEventHandler()->ProcessEvent(event);
316
317 }
318
319 static void
320 wxgtk_webview_webkit_resource_req(WebKitWebView *,
321 WebKitWebFrame *,
322 WebKitWebResource *,
323 WebKitNetworkRequest *request,
324 WebKitNetworkResponse *,
325 wxWebViewWebKit *webKitCtrl)
326 {
327 wxString uri = webkit_network_request_get_uri(request);
328
329 wxSharedPtr<wxWebViewHandler> handler;
330 wxVector<wxSharedPtr<wxWebViewHandler> > hanlders = webKitCtrl->GetHandlers();
331
332 //We are not vetoed so see if we match one of the additional handlers
333 for(wxVector<wxSharedPtr<wxWebViewHandler> >::iterator it = hanlders.begin();
334 it != hanlders.end(); ++it)
335 {
336 if(uri.substr(0, (*it)->GetName().length()) == (*it)->GetName())
337 {
338 handler = (*it);
339 }
340 }
341 //If we found a handler we can then use it to load the file directly
342 //ourselves
343 if(handler)
344 {
345 //If it is requsting the page itself then return as we have already
346 //loaded it from the archive
347 if(webKitCtrl->m_vfsurl == uri)
348 return;
349
350 wxFSFile* file = handler->GetFile(uri);
351 if(file)
352 {
353 //We load the data into a data url to save it being written out again
354 size_t size = file->GetStream()->GetLength();
355 char *buffer = new char[size];
356 file->GetStream()->Read(buffer, size);
357 wxString data = wxBase64Encode(buffer, size);
358 delete[] buffer;
359 wxString mime = file->GetMimeType();
360 wxString path = "data:" + mime + ";base64," + data;
361 //Then we can redirect the call
362 webkit_network_request_set_uri(request, path);
363 }
364
365 }
366 }
367
368 } // extern "C"
369
370 //-----------------------------------------------------------------------------
371 // wxWebViewWebKit
372 //-----------------------------------------------------------------------------
373
374 wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewWebKit, wxWebView);
375
376 bool wxWebViewWebKit::Create(wxWindow *parent,
377 wxWindowID id,
378 const wxString &url,
379 const wxPoint& pos,
380 const wxSize& size,
381 long style,
382 const wxString& name)
383 {
384 m_ready = false;
385 m_busy = false;
386 m_guard = false;
387
388 if (!PreCreation( parent, pos, size ) ||
389 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
390 {
391 wxFAIL_MSG( wxT("wxWebViewWebKit creation failed") );
392 return false;
393 }
394
395 GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
396 web_view = webkit_web_view_new ();
397 g_object_ref(web_view); // TODO: check memory management
398
399 m_widget = scrolled_window;
400 g_object_ref(m_widget); // TODO: check memory management
401
402 /* Place the WebKitWebView in the GtkScrolledWindow */
403 gtk_container_add (GTK_CONTAINER (scrolled_window), web_view);
404 gtk_widget_show(m_widget);
405 gtk_widget_show(web_view);
406
407 g_signal_connect_after(web_view, "notify::load-status",
408 G_CALLBACK(wxgtk_webview_webkit_load_status),
409 this);
410 g_signal_connect_after(web_view, "navigation-policy-decision-requested",
411 G_CALLBACK(wxgtk_webview_webkit_navigation),
412 this);
413 g_signal_connect_after(web_view, "load-error",
414 G_CALLBACK(wxgtk_webview_webkit_error),
415 this);
416
417 g_signal_connect_after(web_view, "new-window-policy-decision-requested",
418 G_CALLBACK(wxgtk_webview_webkit_new_window), this);
419
420 g_signal_connect_after(web_view, "title-changed",
421 G_CALLBACK(wxgtk_webview_webkit_title_changed), this);
422
423 g_signal_connect_after(web_view, "resource-request-starting",
424 G_CALLBACK(wxgtk_webview_webkit_resource_req), this);
425
426 m_parent->DoAddChild( this );
427
428 PostCreation(size);
429
430 /* Open a webpage */
431 webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), url);
432
433 //Get the initial history limit so we can enable and disable it later
434 WebKitWebBackForwardList* history;
435 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
436 m_historyLimit = webkit_web_back_forward_list_get_limit(history);
437
438 m_ready = true;
439
440 return true;
441 }
442
443 bool wxWebViewWebKit::Enable( bool enable )
444 {
445 if (!wxControl::Enable(enable))
446 return false;
447
448 gtk_widget_set_sensitive(GTK_BIN(m_widget)->child, enable);
449
450 //if (enable)
451 // GTKFixSensitivity();
452
453 return true;
454 }
455
456 GdkWindow*
457 wxWebViewWebKit::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
458 {
459 GdkWindow* window = gtk_widget_get_parent_window(m_widget);
460 return window;
461 }
462
463 void wxWebViewWebKit::ZoomIn()
464 {
465 webkit_web_view_zoom_in (WEBKIT_WEB_VIEW(web_view));
466 }
467
468 void wxWebViewWebKit::ZoomOut()
469 {
470 webkit_web_view_zoom_out (WEBKIT_WEB_VIEW(web_view));
471 }
472
473 void wxWebViewWebKit::SetWebkitZoom(float level)
474 {
475 webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW(web_view), level);
476 }
477
478 float wxWebViewWebKit::GetWebkitZoom()
479 {
480 return webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW(web_view));
481 }
482
483 void wxWebViewWebKit::Stop()
484 {
485 webkit_web_view_stop_loading (WEBKIT_WEB_VIEW(web_view));
486 }
487
488 void wxWebViewWebKit::Reload(wxWebViewReloadFlags flags)
489 {
490 if (flags & wxWEB_VIEW_RELOAD_NO_CACHE)
491 {
492 webkit_web_view_reload_bypass_cache (WEBKIT_WEB_VIEW(web_view));
493 }
494 else
495 {
496 webkit_web_view_reload (WEBKIT_WEB_VIEW(web_view));
497 }
498 }
499
500 void wxWebViewWebKit::LoadUrl(const wxString& url)
501 {
502 webkit_web_view_load_uri(WEBKIT_WEB_VIEW(web_view), wxGTK_CONV(url));
503 }
504
505
506 void wxWebViewWebKit::GoBack()
507 {
508 webkit_web_view_go_back (WEBKIT_WEB_VIEW(web_view));
509 }
510
511 void wxWebViewWebKit::GoForward()
512 {
513 webkit_web_view_go_forward (WEBKIT_WEB_VIEW(web_view));
514 }
515
516
517 bool wxWebViewWebKit::CanGoBack()
518 {
519 return webkit_web_view_can_go_back (WEBKIT_WEB_VIEW(web_view));
520 }
521
522
523 bool wxWebViewWebKit::CanGoForward()
524 {
525 return webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW(web_view));
526 }
527
528 void wxWebViewWebKit::ClearHistory()
529 {
530 WebKitWebBackForwardList* history;
531 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
532 webkit_web_back_forward_list_clear(history);
533 }
534
535 void wxWebViewWebKit::EnableHistory(bool enable)
536 {
537 WebKitWebBackForwardList* history;
538 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
539 if(enable)
540 {
541 webkit_web_back_forward_list_set_limit(history, m_historyLimit);
542 }
543 else
544 {
545 webkit_web_back_forward_list_set_limit(history, 0);
546 }
547 }
548
549 wxVector<wxSharedPtr<wxWebHistoryItem> > wxWebViewWebKit::GetBackwardHistory()
550 {
551 wxVector<wxSharedPtr<wxWebHistoryItem> > backhist;
552 WebKitWebBackForwardList* history;
553 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
554 GList* list = webkit_web_back_forward_list_get_back_list_with_limit(history,
555 m_historyLimit);
556 //We need to iterate in reverse to get the order we desire
557 for(int i = g_list_length(list) - 1; i >= 0 ; i--)
558 {
559 WebKitWebHistoryItem* gtkitem = (WebKitWebHistoryItem*)g_list_nth_data(list, i);
560 wxWebHistoryItem* wxitem = new wxWebHistoryItem(
561 webkit_web_history_item_get_uri(gtkitem),
562 webkit_web_history_item_get_title(gtkitem));
563 wxitem->m_histItem = gtkitem;
564 wxSharedPtr<wxWebHistoryItem> item(wxitem);
565 backhist.push_back(item);
566 }
567 return backhist;
568 }
569
570 wxVector<wxSharedPtr<wxWebHistoryItem> > wxWebViewWebKit::GetForwardHistory()
571 {
572 wxVector<wxSharedPtr<wxWebHistoryItem> > forwardhist;
573 WebKitWebBackForwardList* history;
574 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
575 GList* list = webkit_web_back_forward_list_get_forward_list_with_limit(history,
576 m_historyLimit);
577 for(guint i = 0; i < g_list_length(list); i++)
578 {
579 WebKitWebHistoryItem* gtkitem = (WebKitWebHistoryItem*)g_list_nth_data(list, i);
580 wxWebHistoryItem* wxitem = new wxWebHistoryItem(
581 webkit_web_history_item_get_uri(gtkitem),
582 webkit_web_history_item_get_title(gtkitem));
583 wxitem->m_histItem = gtkitem;
584 wxSharedPtr<wxWebHistoryItem> item(wxitem);
585 forwardhist.push_back(item);
586 }
587 return forwardhist;
588 }
589
590 void wxWebViewWebKit::LoadHistoryItem(wxSharedPtr<wxWebHistoryItem> item)
591 {
592 WebKitWebHistoryItem* gtkitem = item->m_histItem;
593 if(gtkitem)
594 {
595 WebKitWebBackForwardList* history;
596 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
597 webkit_web_view_go_to_back_forward_item(WEBKIT_WEB_VIEW(web_view),
598 WEBKIT_WEB_HISTORY_ITEM(gtkitem));
599 }
600 }
601
602 bool wxWebViewWebKit::CanCut()
603 {
604 return webkit_web_view_can_cut_clipboard(WEBKIT_WEB_VIEW(web_view));
605 }
606
607 bool wxWebViewWebKit::CanCopy()
608 {
609 return webkit_web_view_can_copy_clipboard(WEBKIT_WEB_VIEW(web_view));
610 }
611
612 bool wxWebViewWebKit::CanPaste()
613 {
614 return webkit_web_view_can_paste_clipboard(WEBKIT_WEB_VIEW(web_view));
615 }
616
617 void wxWebViewWebKit::Cut()
618 {
619 webkit_web_view_cut_clipboard(WEBKIT_WEB_VIEW(web_view));
620 }
621
622 void wxWebViewWebKit::Copy()
623 {
624 webkit_web_view_copy_clipboard(WEBKIT_WEB_VIEW(web_view));
625 }
626
627 void wxWebViewWebKit::Paste()
628 {
629 webkit_web_view_paste_clipboard(WEBKIT_WEB_VIEW(web_view));
630 }
631
632 bool wxWebViewWebKit::CanUndo()
633 {
634 return webkit_web_view_can_undo(WEBKIT_WEB_VIEW(web_view));
635 }
636
637 bool wxWebViewWebKit::CanRedo()
638 {
639 return webkit_web_view_can_redo(WEBKIT_WEB_VIEW(web_view));
640 }
641
642 void wxWebViewWebKit::Undo()
643 {
644 webkit_web_view_undo(WEBKIT_WEB_VIEW(web_view));
645 }
646
647 void wxWebViewWebKit::Redo()
648 {
649 webkit_web_view_redo(WEBKIT_WEB_VIEW(web_view));
650 }
651
652 wxString wxWebViewWebKit::GetCurrentURL()
653 {
654 // FIXME: check which encoding the web kit control uses instead of
655 // assuming UTF8 (here and elsewhere too)
656 return wxString::FromUTF8(webkit_web_view_get_uri(
657 WEBKIT_WEB_VIEW(web_view)));
658 }
659
660
661 wxString wxWebViewWebKit::GetCurrentTitle()
662 {
663 return wxString::FromUTF8(webkit_web_view_get_title(
664 WEBKIT_WEB_VIEW(web_view)));
665 }
666
667
668 wxString wxWebViewWebKit::GetPageSource()
669 {
670 WebKitWebFrame* frame = webkit_web_view_get_main_frame(
671 WEBKIT_WEB_VIEW(web_view));
672 WebKitWebDataSource* src = webkit_web_frame_get_data_source (frame);
673
674 // TODO: check encoding with
675 // const gchar*
676 // webkit_web_data_source_get_encoding(WebKitWebDataSource *data_source);
677 return wxString(webkit_web_data_source_get_data (src)->str, wxConvUTF8);
678 }
679
680
681 wxWebViewZoom wxWebViewWebKit::GetZoom()
682 {
683 float zoom = GetWebkitZoom();
684
685 // arbitrary way to map float zoom to our common zoom enum
686 if (zoom <= 0.65)
687 {
688 return wxWEB_VIEW_ZOOM_TINY;
689 }
690 else if (zoom > 0.65 && zoom <= 0.90)
691 {
692 return wxWEB_VIEW_ZOOM_SMALL;
693 }
694 else if (zoom > 0.90 && zoom <= 1.15)
695 {
696 return wxWEB_VIEW_ZOOM_MEDIUM;
697 }
698 else if (zoom > 1.15 && zoom <= 1.45)
699 {
700 return wxWEB_VIEW_ZOOM_LARGE;
701 }
702 else if (zoom > 1.45)
703 {
704 return wxWEB_VIEW_ZOOM_LARGEST;
705 }
706
707 // to shut up compilers, this can never be reached logically
708 wxASSERT(false);
709 return wxWEB_VIEW_ZOOM_MEDIUM;
710 }
711
712
713 void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom)
714 {
715 // arbitrary way to map our common zoom enum to float zoom
716 switch (zoom)
717 {
718 case wxWEB_VIEW_ZOOM_TINY:
719 SetWebkitZoom(0.6f);
720 break;
721
722 case wxWEB_VIEW_ZOOM_SMALL:
723 SetWebkitZoom(0.8f);
724 break;
725
726 case wxWEB_VIEW_ZOOM_MEDIUM:
727 SetWebkitZoom(1.0f);
728 break;
729
730 case wxWEB_VIEW_ZOOM_LARGE:
731 SetWebkitZoom(1.3);
732 break;
733
734 case wxWEB_VIEW_ZOOM_LARGEST:
735 SetWebkitZoom(1.6);
736 break;
737
738 default:
739 wxASSERT(false);
740 }
741 }
742
743 void wxWebViewWebKit::SetZoomType(wxWebViewZoomType type)
744 {
745 webkit_web_view_set_full_content_zoom(WEBKIT_WEB_VIEW(web_view),
746 (type == wxWEB_VIEW_ZOOM_TYPE_LAYOUT ?
747 TRUE : FALSE));
748 }
749
750 wxWebViewZoomType wxWebViewWebKit::GetZoomType() const
751 {
752 gboolean fczoom = webkit_web_view_get_full_content_zoom(
753 WEBKIT_WEB_VIEW(web_view));
754
755 if (fczoom) return wxWEB_VIEW_ZOOM_TYPE_LAYOUT;
756 else return wxWEB_VIEW_ZOOM_TYPE_TEXT;
757 }
758
759 bool wxWebViewWebKit::CanSetZoomType(wxWebViewZoomType) const
760 {
761 // this port supports all zoom types
762 return true;
763 }
764
765 void wxWebViewWebKit::SetPage(const wxString& html, const wxString& baseUri)
766 {
767 webkit_web_view_load_string (WEBKIT_WEB_VIEW(web_view),
768 html.mb_str(wxConvUTF8),
769 "text/html",
770 "UTF-8",
771 baseUri.mb_str(wxConvUTF8));
772 }
773
774 void wxWebViewWebKit::Print()
775 {
776 WebKitWebFrame* frame = webkit_web_view_get_main_frame(
777 WEBKIT_WEB_VIEW(web_view));
778 webkit_web_frame_print (frame);
779
780 // GtkPrintOperationResult webkit_web_frame_print_full
781 // (WebKitWebFrame *frame,
782 // GtkPrintOperation *operation,
783 // GtkPrintOperationAction action,
784 // GError **error);
785
786 }
787
788
789 bool wxWebViewWebKit::IsBusy()
790 {
791 return m_busy;
792
793 // This code looks nice but returns true after a page was cancelled
794 /*
795 WebKitLoadStatus status = webkit_web_view_get_load_status
796 (WEBKIT_WEB_VIEW(web_view));
797
798
799 #if WEBKIT_CHECK_VERSION(1,1,16)
800 // WEBKIT_LOAD_FAILED is new in webkit 1.1.16
801 if (status == WEBKIT_LOAD_FAILED)
802 {
803 return false;
804 }
805 #endif
806 if (status == WEBKIT_LOAD_FINISHED)
807 {
808 return false;
809 }
810
811 return true;
812 */
813 }
814
815 void wxWebViewWebKit::SetEditable(bool enable)
816 {
817 webkit_web_view_set_editable(WEBKIT_WEB_VIEW(web_view), enable);
818 }
819
820 bool wxWebViewWebKit::IsEditable()
821 {
822 return webkit_web_view_get_editable(WEBKIT_WEB_VIEW(web_view));
823 }
824
825 void wxWebViewWebKit::DeleteSelection()
826 {
827 webkit_web_view_delete_selection(WEBKIT_WEB_VIEW(web_view));
828 }
829
830 bool wxWebViewWebKit::HasSelection()
831 {
832 return webkit_web_view_has_selection(WEBKIT_WEB_VIEW(web_view));
833 }
834
835 void wxWebViewWebKit::SelectAll()
836 {
837 webkit_web_view_select_all(WEBKIT_WEB_VIEW(web_view));
838 }
839
840 wxString wxWebViewWebKit::GetSelectedText()
841 {
842 WebKitDOMDocument* doc;
843 WebKitDOMDOMWindow* win;
844 WebKitDOMDOMSelection* sel;
845 WebKitDOMRange* range;
846
847 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view));
848 win = webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc));
849 sel = webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win));
850 range = webkit_dom_dom_selection_get_range_at(WEBKIT_DOM_DOM_SELECTION(sel),
851 0, NULL);
852 return wxString(webkit_dom_range_get_text(WEBKIT_DOM_RANGE(range)),
853 wxConvUTF8);
854 }
855
856 wxString wxWebViewWebKit::GetSelectedSource()
857 {
858 WebKitDOMDocument* doc;
859 WebKitDOMDOMWindow* win;
860 WebKitDOMDOMSelection* sel;
861 WebKitDOMRange* range;
862 WebKitDOMElement* div;
863 WebKitDOMDocumentFragment* clone;
864 WebKitDOMHTMLElement* html;
865
866 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view));
867 win = webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc));
868 sel = webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win));
869 range = webkit_dom_dom_selection_get_range_at(WEBKIT_DOM_DOM_SELECTION(sel),
870 0, NULL);
871 div = webkit_dom_document_create_element(WEBKIT_DOM_DOCUMENT(doc), "div", NULL);
872
873 clone = webkit_dom_range_clone_contents(WEBKIT_DOM_RANGE(range), NULL);
874 webkit_dom_node_append_child(&div->parent_instance, &clone->parent_instance, NULL);
875 html = (WebKitDOMHTMLElement*)div;
876
877 return wxString(webkit_dom_html_element_get_inner_html(WEBKIT_DOM_HTML_ELEMENT(html)),
878 wxConvUTF8);
879 }
880
881 void wxWebViewWebKit::ClearSelection()
882 {
883 WebKitDOMDocument* doc;
884 WebKitDOMDOMWindow* win;
885 WebKitDOMDOMSelection* sel;
886
887 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view));
888 win = webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc));
889 sel = webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win));
890 webkit_dom_dom_selection_remove_all_ranges(WEBKIT_DOM_DOM_SELECTION(sel));
891
892 }
893
894 wxString wxWebViewWebKit::GetPageText()
895 {
896 WebKitDOMDocument* doc;
897 WebKitDOMHTMLElement* body;
898
899 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view));
900 body = webkit_dom_document_get_body(WEBKIT_DOM_DOCUMENT(doc));
901 return wxString(webkit_dom_html_element_get_inner_text(WEBKIT_DOM_HTML_ELEMENT(body)),
902 wxConvUTF8);
903 }
904
905 void wxWebViewWebKit::RunScript(const wxString& javascript)
906 {
907 webkit_web_view_execute_script(WEBKIT_WEB_VIEW(web_view),
908 javascript.mb_str(wxConvUTF8));
909 }
910
911 void wxWebViewWebKit::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler)
912 {
913 m_handlerList.push_back(handler);
914 }
915
916 // static
917 wxVisualAttributes
918 wxWebViewWebKit::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
919 {
920 return GetDefaultAttributesFromGTKWidget(webkit_web_view_new);
921 }
922
923
924 #endif // wxHAVE_WEB_BACKEND_GTK_WEBKIT