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