]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/webview_webkit.cpp
Added wxRichTextXMLHandler::RegisterNodeName so custom content classes can be added...
[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 && 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 wxString url = webKitCtrl->GetCurrentURL();
36
37 WebKitLoadStatus status;
38 g_object_get(G_OBJECT(widget), "load-status", &status, NULL);
39
40 wxString target; // TODO: get target (if possible)
41
42 if (status == WEBKIT_LOAD_FINISHED)
43 {
44 WebKitWebBackForwardList* hist = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(widget));
45 WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_current_item(hist);
46 //We have to check if we are actually storing history
47 //If the item isn't added we add it ourselves, it isn't added otherwise
48 //with a custom scheme.
49 if(WEBKIT_IS_WEB_HISTORY_ITEM(item) && webkit_web_history_item_get_uri(item) != url)
50 {
51 WebKitWebHistoryItem*
52 newitem = webkit_web_history_item_new_with_data
53 (
54 url.utf8_str(),
55 webKitCtrl->GetCurrentTitle().utf8_str()
56 );
57 webkit_web_back_forward_list_add_item(hist, newitem);
58 }
59
60 webKitCtrl->m_busy = false;
61 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_LOADED,
62 webKitCtrl->GetId(),
63 url, target);
64
65 if (webKitCtrl && webKitCtrl->GetEventHandler())
66 webKitCtrl->GetEventHandler()->ProcessEvent(event);
67 }
68 else if (status == WEBKIT_LOAD_COMMITTED)
69 {
70 webKitCtrl->m_busy = true;
71 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED,
72 webKitCtrl->GetId(),
73 url, target);
74
75 if (webKitCtrl && webKitCtrl->GetEventHandler())
76 webKitCtrl->GetEventHandler()->ProcessEvent(event);
77 }
78 }
79
80 static gboolean
81 wxgtk_webview_webkit_navigation(WebKitWebView *,
82 WebKitWebFrame *frame,
83 WebKitNetworkRequest *request,
84 WebKitWebNavigationAction *,
85 WebKitWebPolicyDecision *policy_decision,
86 wxWebViewWebKit *webKitCtrl)
87 {
88 if(webKitCtrl->m_guard)
89 {
90 webKitCtrl->m_guard = false;
91 //We set this to make sure that we don't try to load the page again from
92 //the resource request callback
93 webKitCtrl->m_vfsurl = webkit_network_request_get_uri(request);
94 webkit_web_policy_decision_use(policy_decision);
95 return FALSE;
96 }
97
98 webKitCtrl->m_busy = true;
99
100 const gchar* uri = webkit_network_request_get_uri(request);
101
102 wxString target = webkit_web_frame_get_name (frame);
103 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATING,
104 webKitCtrl->GetId(),
105 wxString( uri, wxConvUTF8 ),
106 target);
107
108 if (webKitCtrl && webKitCtrl->GetEventHandler())
109 webKitCtrl->GetEventHandler()->ProcessEvent(event);
110
111 if (!event.IsAllowed())
112 {
113 webKitCtrl->m_busy = false;
114 webkit_web_policy_decision_ignore(policy_decision);
115 return TRUE;
116 }
117 else
118 {
119 wxString wxuri = uri;
120 wxSharedPtr<wxWebViewHandler> handler;
121 wxVector<wxSharedPtr<wxWebViewHandler> > hanlders = webKitCtrl->GetHandlers();
122 //We are not vetoed so see if we match one of the additional handlers
123 for(wxVector<wxSharedPtr<wxWebViewHandler> >::iterator it = hanlders.begin();
124 it != hanlders.end(); ++it)
125 {
126 if(wxuri.substr(0, (*it)->GetName().length()) == (*it)->GetName())
127 {
128 handler = (*it);
129 }
130 }
131 //If we found a handler we can then use it to load the file directly
132 //ourselves
133 if(handler)
134 {
135 webKitCtrl->m_guard = true;
136 wxFSFile* file = handler->GetFile(wxuri);
137 if(file)
138 {
139 webKitCtrl->SetPage(*file->GetStream(), wxuri);
140 }
141 //We need to throw some sort of error here if file is NULL
142 webkit_web_policy_decision_ignore(policy_decision);
143 return TRUE;
144 }
145 return FALSE;
146 }
147 }
148
149 static gboolean
150 wxgtk_webview_webkit_error(WebKitWebView*,
151 WebKitWebFrame*,
152 gchar *uri,
153 gpointer web_error,
154 wxWebViewWebKit* webKitWindow)
155 {
156 webKitWindow->m_busy = false;
157 wxWebViewNavigationError type = wxWEB_NAV_ERR_OTHER;
158
159 GError* error = (GError*)web_error;
160 wxString description(error->message, wxConvUTF8);
161
162 if (strcmp(g_quark_to_string(error->domain), "soup_http_error_quark") == 0)
163 {
164 switch (error->code)
165 {
166 case SOUP_STATUS_CANCELLED:
167 type = wxWEB_NAV_ERR_USER_CANCELLED;
168 break;
169
170 case SOUP_STATUS_CANT_RESOLVE:
171 case SOUP_STATUS_NOT_FOUND:
172 type = wxWEB_NAV_ERR_NOT_FOUND;
173 break;
174
175 case SOUP_STATUS_CANT_RESOLVE_PROXY:
176 case SOUP_STATUS_CANT_CONNECT:
177 case SOUP_STATUS_CANT_CONNECT_PROXY:
178 case SOUP_STATUS_SSL_FAILED:
179 case SOUP_STATUS_IO_ERROR:
180 type = wxWEB_NAV_ERR_CONNECTION;
181 break;
182
183 case SOUP_STATUS_MALFORMED:
184 //case SOUP_STATUS_TOO_MANY_REDIRECTS:
185 type = wxWEB_NAV_ERR_REQUEST;
186 break;
187
188 //case SOUP_STATUS_NO_CONTENT:
189 //case SOUP_STATUS_RESET_CONTENT:
190
191 case SOUP_STATUS_BAD_REQUEST:
192 type = wxWEB_NAV_ERR_REQUEST;
193 break;
194
195 case SOUP_STATUS_UNAUTHORIZED:
196 case SOUP_STATUS_FORBIDDEN:
197 type = wxWEB_NAV_ERR_AUTH;
198 break;
199
200 case SOUP_STATUS_METHOD_NOT_ALLOWED:
201 case SOUP_STATUS_NOT_ACCEPTABLE:
202 type = wxWEB_NAV_ERR_SECURITY;
203 break;
204
205 case SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED:
206 type = wxWEB_NAV_ERR_AUTH;
207 break;
208
209 case SOUP_STATUS_REQUEST_TIMEOUT:
210 type = wxWEB_NAV_ERR_CONNECTION;
211 break;
212
213 //case SOUP_STATUS_PAYMENT_REQUIRED:
214 case SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE:
215 case SOUP_STATUS_REQUEST_URI_TOO_LONG:
216 case SOUP_STATUS_UNSUPPORTED_MEDIA_TYPE:
217 type = wxWEB_NAV_ERR_REQUEST;
218 break;
219
220 case SOUP_STATUS_BAD_GATEWAY:
221 case SOUP_STATUS_SERVICE_UNAVAILABLE:
222 case SOUP_STATUS_GATEWAY_TIMEOUT:
223 type = wxWEB_NAV_ERR_CONNECTION;
224 break;
225
226 case SOUP_STATUS_HTTP_VERSION_NOT_SUPPORTED:
227 type = wxWEB_NAV_ERR_REQUEST;
228 break;
229 //case SOUP_STATUS_INSUFFICIENT_STORAGE:
230 //case SOUP_STATUS_NOT_EXTENDED:
231 }
232 }
233 else if (strcmp(g_quark_to_string(error->domain),
234 "webkit-network-error-quark") == 0)
235 {
236 switch (error->code)
237 {
238 //WEBKIT_NETWORK_ERROR_FAILED:
239 //WEBKIT_NETWORK_ERROR_TRANSPORT:
240
241 case WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL:
242 type = wxWEB_NAV_ERR_REQUEST;
243 break;
244
245 case WEBKIT_NETWORK_ERROR_CANCELLED:
246 type = wxWEB_NAV_ERR_USER_CANCELLED;
247 break;
248
249 case WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST:
250 type = wxWEB_NAV_ERR_NOT_FOUND;
251 break;
252 }
253 }
254 else if (strcmp(g_quark_to_string(error->domain),
255 "webkit-policy-error-quark") == 0)
256 {
257 switch (error->code)
258 {
259 //case WEBKIT_POLICY_ERROR_FAILED:
260 //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE:
261 //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_URL:
262 //case WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE:
263 case WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT:
264 type = wxWEB_NAV_ERR_SECURITY;
265 break;
266 }
267 }
268 /*
269 webkit_plugin_error_quark
270 else
271 {
272 printf("Error domain %s\n", g_quark_to_string(error->domain));
273 }
274 */
275
276 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_ERROR,
277 webKitWindow->GetId(),
278 uri, "");
279 event.SetString(description);
280 event.SetInt(type);
281
282 if (webKitWindow && webKitWindow->GetEventHandler())
283 {
284 webKitWindow->GetEventHandler()->ProcessEvent(event);
285 }
286
287 return FALSE;
288 }
289
290 static gboolean
291 wxgtk_webview_webkit_new_window(WebKitWebView*,
292 WebKitWebFrame *frame,
293 WebKitNetworkRequest *request,
294 WebKitWebNavigationAction*,
295 WebKitWebPolicyDecision *policy_decision,
296 wxWebViewWebKit *webKitCtrl)
297 {
298 const gchar* uri = webkit_network_request_get_uri(request);
299
300 wxString target = webkit_web_frame_get_name (frame);
301 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NEWWINDOW,
302 webKitCtrl->GetId(),
303 wxString( uri, wxConvUTF8 ),
304 target);
305
306 if (webKitCtrl && webKitCtrl->GetEventHandler())
307 webKitCtrl->GetEventHandler()->ProcessEvent(event);
308
309 //We always want the user to handle this themselves
310 webkit_web_policy_decision_ignore(policy_decision);
311 return TRUE;
312 }
313
314 static void
315 wxgtk_webview_webkit_title_changed(WebKitWebView*,
316 WebKitWebFrame*,
317 gchar *title,
318 wxWebViewWebKit *webKitCtrl)
319 {
320 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED,
321 webKitCtrl->GetId(),
322 webKitCtrl->GetCurrentURL(),
323 "");
324 event.SetString(wxString(title, wxConvUTF8));
325
326 if (webKitCtrl && webKitCtrl->GetEventHandler())
327 webKitCtrl->GetEventHandler()->ProcessEvent(event);
328
329 }
330
331 static void
332 wxgtk_webview_webkit_resource_req(WebKitWebView *,
333 WebKitWebFrame *,
334 WebKitWebResource *,
335 WebKitNetworkRequest *request,
336 WebKitNetworkResponse *,
337 wxWebViewWebKit *webKitCtrl)
338 {
339 wxString uri = webkit_network_request_get_uri(request);
340
341 wxSharedPtr<wxWebViewHandler> handler;
342 wxVector<wxSharedPtr<wxWebViewHandler> > hanlders = webKitCtrl->GetHandlers();
343
344 //We are not vetoed so see if we match one of the additional handlers
345 for(wxVector<wxSharedPtr<wxWebViewHandler> >::iterator it = hanlders.begin();
346 it != hanlders.end(); ++it)
347 {
348 if(uri.substr(0, (*it)->GetName().length()) == (*it)->GetName())
349 {
350 handler = (*it);
351 }
352 }
353 //If we found a handler we can then use it to load the file directly
354 //ourselves
355 if(handler)
356 {
357 //If it is requsting the page itself then return as we have already
358 //loaded it from the archive
359 if(webKitCtrl->m_vfsurl == uri)
360 return;
361
362 wxFSFile* file = handler->GetFile(uri);
363 if(file)
364 {
365 //We load the data into a data url to save it being written out again
366 size_t size = file->GetStream()->GetLength();
367 char *buffer = new char[size];
368 file->GetStream()->Read(buffer, size);
369 wxString data = wxBase64Encode(buffer, size);
370 delete[] buffer;
371 wxString mime = file->GetMimeType();
372 wxString path = "data:" + mime + ";base64," + data;
373 //Then we can redirect the call
374 webkit_network_request_set_uri(request, path.utf8_str());
375 }
376
377 }
378 }
379
380 } // extern "C"
381
382 //-----------------------------------------------------------------------------
383 // wxWebViewWebKit
384 //-----------------------------------------------------------------------------
385
386 wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewWebKit, wxWebView);
387
388 bool wxWebViewWebKit::Create(wxWindow *parent,
389 wxWindowID id,
390 const wxString &url,
391 const wxPoint& pos,
392 const wxSize& size,
393 long style,
394 const wxString& name)
395 {
396 m_busy = false;
397 m_guard = false;
398
399 if (!PreCreation( parent, pos, size ) ||
400 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
401 {
402 wxFAIL_MSG( wxT("wxWebViewWebKit creation failed") );
403 return false;
404 }
405
406 m_widget = gtk_scrolled_window_new(NULL, NULL);
407 g_object_ref(m_widget);
408 m_web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
409
410 /* Place the WebKitWebView in the GtkScrolledWindow */
411 gtk_container_add(GTK_CONTAINER(m_widget), GTK_WIDGET(m_web_view));
412 gtk_widget_show(GTK_WIDGET(m_web_view));
413
414 g_signal_connect_after(m_web_view, "navigation-policy-decision-requested",
415 G_CALLBACK(wxgtk_webview_webkit_navigation),
416 this);
417 g_signal_connect_after(m_web_view, "load-error",
418 G_CALLBACK(wxgtk_webview_webkit_error),
419 this);
420
421 g_signal_connect_after(m_web_view, "new-window-policy-decision-requested",
422 G_CALLBACK(wxgtk_webview_webkit_new_window), this);
423
424 g_signal_connect_after(m_web_view, "title-changed",
425 G_CALLBACK(wxgtk_webview_webkit_title_changed), this);
426
427 g_signal_connect_after(m_web_view, "resource-request-starting",
428 G_CALLBACK(wxgtk_webview_webkit_resource_req), this);
429
430 m_parent->DoAddChild( this );
431
432 PostCreation(size);
433
434 /* Open a webpage */
435 webkit_web_view_load_uri(m_web_view, url.utf8_str());
436
437 //Get the initial history limit so we can enable and disable it later
438 WebKitWebBackForwardList* history;
439 history = webkit_web_view_get_back_forward_list(m_web_view);
440 m_historyLimit = webkit_web_back_forward_list_get_limit(history);
441
442 // last to avoid getting signal too early
443 g_signal_connect_after(m_web_view, "notify::load-status",
444 G_CALLBACK(wxgtk_webview_webkit_load_status),
445 this);
446
447 return true;
448 }
449
450 bool wxWebViewWebKit::Enable( bool enable )
451 {
452 if (!wxControl::Enable(enable))
453 return false;
454
455 gtk_widget_set_sensitive(GTK_BIN(m_widget)->child, enable);
456
457 //if (enable)
458 // GTKFixSensitivity();
459
460 return true;
461 }
462
463 GdkWindow*
464 wxWebViewWebKit::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
465 {
466 GdkWindow* window = gtk_widget_get_parent_window(m_widget);
467 return window;
468 }
469
470 void wxWebViewWebKit::ZoomIn()
471 {
472 webkit_web_view_zoom_in(m_web_view);
473 }
474
475 void wxWebViewWebKit::ZoomOut()
476 {
477 webkit_web_view_zoom_out(m_web_view);
478 }
479
480 void wxWebViewWebKit::SetWebkitZoom(float level)
481 {
482 webkit_web_view_set_zoom_level(m_web_view, level);
483 }
484
485 float wxWebViewWebKit::GetWebkitZoom() const
486 {
487 return webkit_web_view_get_zoom_level(m_web_view);
488 }
489
490 void wxWebViewWebKit::Stop()
491 {
492 webkit_web_view_stop_loading(m_web_view);
493 }
494
495 void wxWebViewWebKit::Reload(wxWebViewReloadFlags flags)
496 {
497 if (flags & wxWEB_VIEW_RELOAD_NO_CACHE)
498 {
499 webkit_web_view_reload_bypass_cache(m_web_view);
500 }
501 else
502 {
503 webkit_web_view_reload(m_web_view);
504 }
505 }
506
507 void wxWebViewWebKit::LoadURL(const wxString& url)
508 {
509 webkit_web_view_load_uri(m_web_view, wxGTK_CONV(url));
510 }
511
512
513 void wxWebViewWebKit::GoBack()
514 {
515 webkit_web_view_go_back(m_web_view);
516 }
517
518 void wxWebViewWebKit::GoForward()
519 {
520 webkit_web_view_go_forward(m_web_view);
521 }
522
523
524 bool wxWebViewWebKit::CanGoBack() const
525 {
526 return webkit_web_view_can_go_back(m_web_view);
527 }
528
529
530 bool wxWebViewWebKit::CanGoForward() const
531 {
532 return webkit_web_view_can_go_forward(m_web_view);
533 }
534
535 void wxWebViewWebKit::ClearHistory()
536 {
537 WebKitWebBackForwardList* history;
538 history = webkit_web_view_get_back_forward_list(m_web_view);
539 webkit_web_back_forward_list_clear(history);
540 }
541
542 void wxWebViewWebKit::EnableHistory(bool enable)
543 {
544 WebKitWebBackForwardList* history;
545 history = webkit_web_view_get_back_forward_list(m_web_view);
546 if(enable)
547 {
548 webkit_web_back_forward_list_set_limit(history, m_historyLimit);
549 }
550 else
551 {
552 webkit_web_back_forward_list_set_limit(history, 0);
553 }
554 }
555
556 wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewWebKit::GetBackwardHistory()
557 {
558 wxVector<wxSharedPtr<wxWebViewHistoryItem> > backhist;
559 WebKitWebBackForwardList* history;
560 history = webkit_web_view_get_back_forward_list(m_web_view);
561 GList* list = webkit_web_back_forward_list_get_back_list_with_limit(history,
562 m_historyLimit);
563 //We need to iterate in reverse to get the order we desire
564 for(int i = g_list_length(list) - 1; i >= 0 ; i--)
565 {
566 WebKitWebHistoryItem* gtkitem = (WebKitWebHistoryItem*)g_list_nth_data(list, i);
567 wxWebViewHistoryItem* wxitem = new wxWebViewHistoryItem(
568 webkit_web_history_item_get_uri(gtkitem),
569 webkit_web_history_item_get_title(gtkitem));
570 wxitem->m_histItem = gtkitem;
571 wxSharedPtr<wxWebViewHistoryItem> item(wxitem);
572 backhist.push_back(item);
573 }
574 return backhist;
575 }
576
577 wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewWebKit::GetForwardHistory()
578 {
579 wxVector<wxSharedPtr<wxWebViewHistoryItem> > forwardhist;
580 WebKitWebBackForwardList* history;
581 history = webkit_web_view_get_back_forward_list(m_web_view);
582 GList* list = webkit_web_back_forward_list_get_forward_list_with_limit(history,
583 m_historyLimit);
584 for(guint i = 0; i < g_list_length(list); i++)
585 {
586 WebKitWebHistoryItem* gtkitem = (WebKitWebHistoryItem*)g_list_nth_data(list, i);
587 wxWebViewHistoryItem* wxitem = new wxWebViewHistoryItem(
588 webkit_web_history_item_get_uri(gtkitem),
589 webkit_web_history_item_get_title(gtkitem));
590 wxitem->m_histItem = gtkitem;
591 wxSharedPtr<wxWebViewHistoryItem> item(wxitem);
592 forwardhist.push_back(item);
593 }
594 return forwardhist;
595 }
596
597 void wxWebViewWebKit::LoadHistoryItem(wxSharedPtr<wxWebViewHistoryItem> item)
598 {
599 WebKitWebHistoryItem* gtkitem = (WebKitWebHistoryItem*)item->m_histItem;
600 if(gtkitem)
601 {
602 webkit_web_view_go_to_back_forward_item(m_web_view,
603 WEBKIT_WEB_HISTORY_ITEM(gtkitem));
604 }
605 }
606
607 bool wxWebViewWebKit::CanCut() const
608 {
609 return webkit_web_view_can_cut_clipboard(m_web_view);
610 }
611
612 bool wxWebViewWebKit::CanCopy() const
613 {
614 return webkit_web_view_can_copy_clipboard(m_web_view);
615 }
616
617 bool wxWebViewWebKit::CanPaste() const
618 {
619 return webkit_web_view_can_paste_clipboard(m_web_view);
620 }
621
622 void wxWebViewWebKit::Cut()
623 {
624 webkit_web_view_cut_clipboard(m_web_view);
625 }
626
627 void wxWebViewWebKit::Copy()
628 {
629 webkit_web_view_copy_clipboard(m_web_view);
630 }
631
632 void wxWebViewWebKit::Paste()
633 {
634 webkit_web_view_paste_clipboard(m_web_view);
635 }
636
637 bool wxWebViewWebKit::CanUndo() const
638 {
639 return webkit_web_view_can_undo(m_web_view);
640 }
641
642 bool wxWebViewWebKit::CanRedo() const
643 {
644 return webkit_web_view_can_redo(m_web_view);
645 }
646
647 void wxWebViewWebKit::Undo()
648 {
649 webkit_web_view_undo(m_web_view);
650 }
651
652 void wxWebViewWebKit::Redo()
653 {
654 webkit_web_view_redo(m_web_view);
655 }
656
657 wxString wxWebViewWebKit::GetCurrentURL() const
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(m_web_view));
662 }
663
664
665 wxString wxWebViewWebKit::GetCurrentTitle() const
666 {
667 return wxString::FromUTF8(webkit_web_view_get_title(m_web_view));
668 }
669
670
671 wxString wxWebViewWebKit::GetPageSource() const
672 {
673 WebKitWebFrame* frame = webkit_web_view_get_main_frame(m_web_view);
674 WebKitWebDataSource* src = webkit_web_frame_get_data_source (frame);
675
676 // TODO: check encoding with
677 // const gchar*
678 // webkit_web_data_source_get_encoding(WebKitWebDataSource *data_source);
679 return wxString(webkit_web_data_source_get_data (src)->str, wxConvUTF8);
680 }
681
682
683 wxWebViewZoom wxWebViewWebKit::GetZoom() const
684 {
685 float zoom = GetWebkitZoom();
686
687 // arbitrary way to map float zoom to our common zoom enum
688 if (zoom <= 0.65)
689 {
690 return wxWEB_VIEW_ZOOM_TINY;
691 }
692 else if (zoom > 0.65 && zoom <= 0.90)
693 {
694 return wxWEB_VIEW_ZOOM_SMALL;
695 }
696 else if (zoom > 0.90 && zoom <= 1.15)
697 {
698 return wxWEB_VIEW_ZOOM_MEDIUM;
699 }
700 else if (zoom > 1.15 && zoom <= 1.45)
701 {
702 return wxWEB_VIEW_ZOOM_LARGE;
703 }
704 else if (zoom > 1.45)
705 {
706 return wxWEB_VIEW_ZOOM_LARGEST;
707 }
708
709 // to shut up compilers, this can never be reached logically
710 wxASSERT(false);
711 return wxWEB_VIEW_ZOOM_MEDIUM;
712 }
713
714
715 void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom)
716 {
717 // arbitrary way to map our common zoom enum to float zoom
718 switch (zoom)
719 {
720 case wxWEB_VIEW_ZOOM_TINY:
721 SetWebkitZoom(0.6f);
722 break;
723
724 case wxWEB_VIEW_ZOOM_SMALL:
725 SetWebkitZoom(0.8f);
726 break;
727
728 case wxWEB_VIEW_ZOOM_MEDIUM:
729 SetWebkitZoom(1.0f);
730 break;
731
732 case wxWEB_VIEW_ZOOM_LARGE:
733 SetWebkitZoom(1.3);
734 break;
735
736 case wxWEB_VIEW_ZOOM_LARGEST:
737 SetWebkitZoom(1.6);
738 break;
739
740 default:
741 wxASSERT(false);
742 }
743 }
744
745 void wxWebViewWebKit::SetZoomType(wxWebViewZoomType type)
746 {
747 webkit_web_view_set_full_content_zoom(m_web_view,
748 (type == wxWEB_VIEW_ZOOM_TYPE_LAYOUT ?
749 TRUE : FALSE));
750 }
751
752 wxWebViewZoomType wxWebViewWebKit::GetZoomType() const
753 {
754 gboolean fczoom = webkit_web_view_get_full_content_zoom(m_web_view);
755
756 if (fczoom) return wxWEB_VIEW_ZOOM_TYPE_LAYOUT;
757 else return wxWEB_VIEW_ZOOM_TYPE_TEXT;
758 }
759
760 bool wxWebViewWebKit::CanSetZoomType(wxWebViewZoomType) const
761 {
762 // this port supports all zoom types
763 return true;
764 }
765
766 void wxWebViewWebKit::SetPage(const wxString& html, const wxString& baseUri)
767 {
768 webkit_web_view_load_string (m_web_view,
769 html.mb_str(wxConvUTF8),
770 "text/html",
771 "UTF-8",
772 baseUri.mb_str(wxConvUTF8));
773 }
774
775 void wxWebViewWebKit::Print()
776 {
777 WebKitWebFrame* frame = webkit_web_view_get_main_frame(m_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() const
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(m_web_view, enable);
818 }
819
820 bool wxWebViewWebKit::IsEditable() const
821 {
822 return webkit_web_view_get_editable(m_web_view);
823 }
824
825 void wxWebViewWebKit::DeleteSelection()
826 {
827 webkit_web_view_delete_selection(m_web_view);
828 }
829
830 bool wxWebViewWebKit::HasSelection() const
831 {
832 return webkit_web_view_has_selection(m_web_view);
833 }
834
835 void wxWebViewWebKit::SelectAll()
836 {
837 webkit_web_view_select_all(m_web_view);
838 }
839
840 wxString wxWebViewWebKit::GetSelectedText() const
841 {
842 WebKitDOMDocument* doc;
843 WebKitDOMDOMWindow* win;
844 WebKitDOMDOMSelection* sel;
845 WebKitDOMRange* range;
846
847 doc = webkit_web_view_get_dom_document(m_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() const
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(m_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(m_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() const
895 {
896 WebKitDOMDocument* doc;
897 WebKitDOMHTMLElement* body;
898
899 doc = webkit_web_view_get_dom_document(m_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(m_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 // wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT