1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/webview_webkit.cpp
3 // Purpose: GTK WebKit backend for web view component
4 // Author: Marianne Gagnon, Robert Roebling
5 // Copyright: (c) 2010 Marianne Gagnon, 1998 Robert Roebling
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
9 // For compilers that support precompilation, includes "wx.h".
10 #include "wx/wxprec.h"
12 #if wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT
14 #include "wx/stockitem.h"
15 #include "wx/gtk/webview_webkit.h"
16 #include "wx/gtk/control.h"
17 #include "wx/gtk/private.h"
18 #include "wx/filesys.h"
19 #include "wx/base64.h"
21 #include <webkit/webkit.h>
23 // ----------------------------------------------------------------------------
25 // ----------------------------------------------------------------------------
31 wxgtk_webview_webkit_load_status(GtkWidget
* widget
,
33 wxWebViewWebKit
*webKitCtrl
)
35 wxString url
= webKitCtrl
->GetCurrentURL();
37 WebKitLoadStatus status
;
38 g_object_get(G_OBJECT(widget
), "load-status", &status
, NULL
);
40 wxString target
; // TODO: get target (if possible)
42 if (status
== WEBKIT_LOAD_FINISHED
)
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(!item
|| (WEBKIT_IS_WEB_HISTORY_ITEM(item
) &&
50 webkit_web_history_item_get_uri(item
) != url
))
53 newitem
= webkit_web_history_item_new_with_data
56 webKitCtrl
->GetCurrentTitle().utf8_str()
58 webkit_web_back_forward_list_add_item(hist
, newitem
);
61 webKitCtrl
->m_busy
= false;
62 wxWebViewEvent
event(wxEVT_WEBVIEW_LOADED
,
66 if (webKitCtrl
&& webKitCtrl
->GetEventHandler())
67 webKitCtrl
->GetEventHandler()->ProcessEvent(event
);
69 else if (status
== WEBKIT_LOAD_COMMITTED
)
71 webKitCtrl
->m_busy
= true;
72 wxWebViewEvent
event(wxEVT_WEBVIEW_NAVIGATED
,
76 if (webKitCtrl
&& webKitCtrl
->GetEventHandler())
77 webKitCtrl
->GetEventHandler()->ProcessEvent(event
);
82 wxgtk_webview_webkit_navigation(WebKitWebView
*,
83 WebKitWebFrame
*frame
,
84 WebKitNetworkRequest
*request
,
85 WebKitWebNavigationAction
*,
86 WebKitWebPolicyDecision
*policy_decision
,
87 wxWebViewWebKit
*webKitCtrl
)
89 const gchar
* uri
= webkit_network_request_get_uri(request
);
90 wxString target
= webkit_web_frame_get_name (frame
);
92 //If m_creating is true then we are the result of a new window
93 //and so we need to send the event and veto the load
94 if(webKitCtrl
->m_creating
)
96 webKitCtrl
->m_creating
= false;
97 wxWebViewEvent
event(wxEVT_WEBVIEW_NEWWINDOW
,
99 wxString(uri
, wxConvUTF8
),
102 if(webKitCtrl
&& webKitCtrl
->GetEventHandler())
103 webKitCtrl
->GetEventHandler()->ProcessEvent(event
);
105 webkit_web_policy_decision_ignore(policy_decision
);
109 if(webKitCtrl
->m_guard
)
111 webKitCtrl
->m_guard
= false;
112 //We set this to make sure that we don't try to load the page again from
113 //the resource request callback
114 webKitCtrl
->m_vfsurl
= webkit_network_request_get_uri(request
);
115 webkit_web_policy_decision_use(policy_decision
);
119 webKitCtrl
->m_busy
= true;
121 wxWebViewEvent
event(wxEVT_WEBVIEW_NAVIGATING
,
123 wxString( uri
, wxConvUTF8
),
126 if (webKitCtrl
&& webKitCtrl
->GetEventHandler())
127 webKitCtrl
->GetEventHandler()->ProcessEvent(event
);
129 if (!event
.IsAllowed())
131 webKitCtrl
->m_busy
= false;
132 webkit_web_policy_decision_ignore(policy_decision
);
137 wxString wxuri
= uri
;
138 wxSharedPtr
<wxWebViewHandler
> handler
;
139 wxVector
<wxSharedPtr
<wxWebViewHandler
> > hanlders
= webKitCtrl
->GetHandlers();
140 //We are not vetoed so see if we match one of the additional handlers
141 for(wxVector
<wxSharedPtr
<wxWebViewHandler
> >::iterator it
= hanlders
.begin();
142 it
!= hanlders
.end(); ++it
)
144 if(wxuri
.substr(0, (*it
)->GetName().length()) == (*it
)->GetName())
149 //If we found a handler we can then use it to load the file directly
153 webKitCtrl
->m_guard
= true;
154 wxFSFile
* file
= handler
->GetFile(wxuri
);
157 webKitCtrl
->SetPage(*file
->GetStream(), wxuri
);
159 //We need to throw some sort of error here if file is NULL
160 webkit_web_policy_decision_ignore(policy_decision
);
168 wxgtk_webview_webkit_error(WebKitWebView
*,
172 wxWebViewWebKit
* webKitWindow
)
174 webKitWindow
->m_busy
= false;
175 wxWebViewNavigationError type
= wxWEBVIEW_NAV_ERR_OTHER
;
177 GError
* error
= (GError
*)web_error
;
178 wxString
description(error
->message
, wxConvUTF8
);
180 if (strcmp(g_quark_to_string(error
->domain
), "soup_http_error_quark") == 0)
184 case SOUP_STATUS_CANCELLED
:
185 type
= wxWEBVIEW_NAV_ERR_USER_CANCELLED
;
188 case SOUP_STATUS_CANT_RESOLVE
:
189 case SOUP_STATUS_NOT_FOUND
:
190 type
= wxWEBVIEW_NAV_ERR_NOT_FOUND
;
193 case SOUP_STATUS_CANT_RESOLVE_PROXY
:
194 case SOUP_STATUS_CANT_CONNECT
:
195 case SOUP_STATUS_CANT_CONNECT_PROXY
:
196 case SOUP_STATUS_SSL_FAILED
:
197 case SOUP_STATUS_IO_ERROR
:
198 type
= wxWEBVIEW_NAV_ERR_CONNECTION
;
201 case SOUP_STATUS_MALFORMED
:
202 //case SOUP_STATUS_TOO_MANY_REDIRECTS:
203 type
= wxWEBVIEW_NAV_ERR_REQUEST
;
206 //case SOUP_STATUS_NO_CONTENT:
207 //case SOUP_STATUS_RESET_CONTENT:
209 case SOUP_STATUS_BAD_REQUEST
:
210 type
= wxWEBVIEW_NAV_ERR_REQUEST
;
213 case SOUP_STATUS_UNAUTHORIZED
:
214 case SOUP_STATUS_FORBIDDEN
:
215 type
= wxWEBVIEW_NAV_ERR_AUTH
;
218 case SOUP_STATUS_METHOD_NOT_ALLOWED
:
219 case SOUP_STATUS_NOT_ACCEPTABLE
:
220 type
= wxWEBVIEW_NAV_ERR_SECURITY
;
223 case SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED
:
224 type
= wxWEBVIEW_NAV_ERR_AUTH
;
227 case SOUP_STATUS_REQUEST_TIMEOUT
:
228 type
= wxWEBVIEW_NAV_ERR_CONNECTION
;
231 //case SOUP_STATUS_PAYMENT_REQUIRED:
232 case SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE
:
233 case SOUP_STATUS_REQUEST_URI_TOO_LONG
:
234 case SOUP_STATUS_UNSUPPORTED_MEDIA_TYPE
:
235 type
= wxWEBVIEW_NAV_ERR_REQUEST
;
238 case SOUP_STATUS_BAD_GATEWAY
:
239 case SOUP_STATUS_SERVICE_UNAVAILABLE
:
240 case SOUP_STATUS_GATEWAY_TIMEOUT
:
241 type
= wxWEBVIEW_NAV_ERR_CONNECTION
;
244 case SOUP_STATUS_HTTP_VERSION_NOT_SUPPORTED
:
245 type
= wxWEBVIEW_NAV_ERR_REQUEST
;
247 //case SOUP_STATUS_INSUFFICIENT_STORAGE:
248 //case SOUP_STATUS_NOT_EXTENDED:
251 else if (strcmp(g_quark_to_string(error
->domain
),
252 "webkit-network-error-quark") == 0)
256 //WEBKIT_NETWORK_ERROR_FAILED:
257 //WEBKIT_NETWORK_ERROR_TRANSPORT:
259 case WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL
:
260 type
= wxWEBVIEW_NAV_ERR_REQUEST
;
263 case WEBKIT_NETWORK_ERROR_CANCELLED
:
264 type
= wxWEBVIEW_NAV_ERR_USER_CANCELLED
;
267 case WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST
:
268 type
= wxWEBVIEW_NAV_ERR_NOT_FOUND
;
272 else if (strcmp(g_quark_to_string(error
->domain
),
273 "webkit-policy-error-quark") == 0)
277 //case WEBKIT_POLICY_ERROR_FAILED:
278 //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE:
279 //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_URL:
280 //case WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE:
281 case WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT
:
282 type
= wxWEBVIEW_NAV_ERR_SECURITY
;
287 webkit_plugin_error_quark
290 printf("Error domain %s\n", g_quark_to_string(error->domain));
294 wxWebViewEvent
event(wxEVT_WEBVIEW_ERROR
,
295 webKitWindow
->GetId(),
297 event
.SetString(description
);
300 if (webKitWindow
&& webKitWindow
->GetEventHandler())
302 webKitWindow
->GetEventHandler()->ProcessEvent(event
);
309 wxgtk_webview_webkit_new_window(WebKitWebView
*,
310 WebKitWebFrame
*frame
,
311 WebKitNetworkRequest
*request
,
312 WebKitWebNavigationAction
*,
313 WebKitWebPolicyDecision
*policy_decision
,
314 wxWebViewWebKit
*webKitCtrl
)
316 const gchar
* uri
= webkit_network_request_get_uri(request
);
318 wxString target
= webkit_web_frame_get_name (frame
);
319 wxWebViewEvent
event(wxEVT_WEBVIEW_NEWWINDOW
,
321 wxString( uri
, wxConvUTF8
),
324 if (webKitCtrl
&& webKitCtrl
->GetEventHandler())
325 webKitCtrl
->GetEventHandler()->ProcessEvent(event
);
327 //We always want the user to handle this themselves
328 webkit_web_policy_decision_ignore(policy_decision
);
333 wxgtk_webview_webkit_title_changed(WebKitWebView
*,
336 wxWebViewWebKit
*webKitCtrl
)
338 wxWebViewEvent
event(wxEVT_WEBVIEW_TITLE_CHANGED
,
340 webKitCtrl
->GetCurrentURL(),
342 event
.SetString(wxString(title
, wxConvUTF8
));
344 if (webKitCtrl
&& webKitCtrl
->GetEventHandler())
345 webKitCtrl
->GetEventHandler()->ProcessEvent(event
);
350 wxgtk_webview_webkit_resource_req(WebKitWebView
*,
353 WebKitNetworkRequest
*request
,
354 WebKitNetworkResponse
*,
355 wxWebViewWebKit
*webKitCtrl
)
357 wxString uri
= webkit_network_request_get_uri(request
);
359 wxSharedPtr
<wxWebViewHandler
> handler
;
360 wxVector
<wxSharedPtr
<wxWebViewHandler
> > hanlders
= webKitCtrl
->GetHandlers();
362 //We are not vetoed so see if we match one of the additional handlers
363 for(wxVector
<wxSharedPtr
<wxWebViewHandler
> >::iterator it
= hanlders
.begin();
364 it
!= hanlders
.end(); ++it
)
366 if(uri
.substr(0, (*it
)->GetName().length()) == (*it
)->GetName())
371 //If we found a handler we can then use it to load the file directly
375 //If it is requsting the page itself then return as we have already
376 //loaded it from the archive
377 if(webKitCtrl
->m_vfsurl
== uri
)
380 wxFSFile
* file
= handler
->GetFile(uri
);
383 //We load the data into a data url to save it being written out again
384 size_t size
= file
->GetStream()->GetLength();
385 char *buffer
= new char[size
];
386 file
->GetStream()->Read(buffer
, size
);
387 wxString data
= wxBase64Encode(buffer
, size
);
389 wxString mime
= file
->GetMimeType();
390 wxString path
= "data:" + mime
+ ";base64," + data
;
391 //Then we can redirect the call
392 webkit_network_request_set_uri(request
, path
.utf8_str());
398 #if WEBKIT_CHECK_VERSION(1, 10, 0)
401 wxgtk_webview_webkit_context_menu(WebKitWebView
*,
403 WebKitHitTestResult
*,
405 wxWebViewWebKit
*webKitCtrl
)
407 if(webKitCtrl
->IsContextMenuEnabled())
415 static WebKitWebView
*
416 wxgtk_webview_webkit_create_webview(WebKitWebView
*web_view
,
417 WebKitWebFrame
*frame
,
418 wxWebViewWebKit
*webKitCtrl
)
420 //As we do not know the uri being loaded at this point allow the load to
421 //continue and catch it in navigation-policy-decision-requested
422 webKitCtrl
->m_creating
= true;
428 //-----------------------------------------------------------------------------
430 //-----------------------------------------------------------------------------
432 wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewWebKit
, wxWebView
);
434 wxWebViewWebKit::wxWebViewWebKit()
439 bool wxWebViewWebKit::Create(wxWindow
*parent
,
445 const wxString
& name
)
452 // We currently unconditionally impose scrolling in both directions as it's
453 // necessary to show arbitrary pages.
454 style
|= wxHSCROLL
| wxVSCROLL
;
456 if (!PreCreation( parent
, pos
, size
) ||
457 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
459 wxFAIL_MSG( wxT("wxWebViewWebKit creation failed") );
463 m_web_view
= WEBKIT_WEB_VIEW(webkit_web_view_new());
464 GTKCreateScrolledWindowWith(GTK_WIDGET(m_web_view
));
465 g_object_ref(m_widget
);
467 g_signal_connect_after(m_web_view
, "navigation-policy-decision-requested",
468 G_CALLBACK(wxgtk_webview_webkit_navigation
),
470 g_signal_connect_after(m_web_view
, "load-error",
471 G_CALLBACK(wxgtk_webview_webkit_error
),
474 g_signal_connect_after(m_web_view
, "new-window-policy-decision-requested",
475 G_CALLBACK(wxgtk_webview_webkit_new_window
), this);
477 g_signal_connect_after(m_web_view
, "title-changed",
478 G_CALLBACK(wxgtk_webview_webkit_title_changed
), this);
480 g_signal_connect_after(m_web_view
, "resource-request-starting",
481 G_CALLBACK(wxgtk_webview_webkit_resource_req
), this);
483 #if WEBKIT_CHECK_VERSION(1, 10, 0)
484 g_signal_connect_after(m_web_view
, "context-menu",
485 G_CALLBACK(wxgtk_webview_webkit_context_menu
), this);
488 g_signal_connect_after(m_web_view
, "create-web-view",
489 G_CALLBACK(wxgtk_webview_webkit_create_webview
), this);
491 m_parent
->DoAddChild( this );
496 webkit_web_view_load_uri(m_web_view
, url
.utf8_str());
498 //Get the initial history limit so we can enable and disable it later
499 WebKitWebBackForwardList
* history
;
500 history
= webkit_web_view_get_back_forward_list(m_web_view
);
501 m_historyLimit
= webkit_web_back_forward_list_get_limit(history
);
503 // last to avoid getting signal too early
504 g_signal_connect_after(m_web_view
, "notify::load-status",
505 G_CALLBACK(wxgtk_webview_webkit_load_status
),
511 wxWebViewWebKit::~wxWebViewWebKit()
514 GTKDisconnect(m_web_view
);
517 bool wxWebViewWebKit::Enable( bool enable
)
519 if (!wxControl::Enable(enable
))
522 gtk_widget_set_sensitive(gtk_bin_get_child(GTK_BIN(m_widget
)), enable
);
525 // GTKFixSensitivity();
531 wxWebViewWebKit::GTKGetWindow(wxArrayGdkWindows
& WXUNUSED(windows
)) const
533 GdkWindow
* window
= gtk_widget_get_parent_window(m_widget
);
537 void wxWebViewWebKit::ZoomIn()
539 webkit_web_view_zoom_in(m_web_view
);
542 void wxWebViewWebKit::ZoomOut()
544 webkit_web_view_zoom_out(m_web_view
);
547 void wxWebViewWebKit::SetWebkitZoom(float level
)
549 webkit_web_view_set_zoom_level(m_web_view
, level
);
552 float wxWebViewWebKit::GetWebkitZoom() const
554 return webkit_web_view_get_zoom_level(m_web_view
);
557 void wxWebViewWebKit::Stop()
559 webkit_web_view_stop_loading(m_web_view
);
562 void wxWebViewWebKit::Reload(wxWebViewReloadFlags flags
)
564 if (flags
& wxWEBVIEW_RELOAD_NO_CACHE
)
566 webkit_web_view_reload_bypass_cache(m_web_view
);
570 webkit_web_view_reload(m_web_view
);
574 void wxWebViewWebKit::LoadURL(const wxString
& url
)
576 webkit_web_view_load_uri(m_web_view
, wxGTK_CONV(url
));
580 void wxWebViewWebKit::GoBack()
582 webkit_web_view_go_back(m_web_view
);
585 void wxWebViewWebKit::GoForward()
587 webkit_web_view_go_forward(m_web_view
);
591 bool wxWebViewWebKit::CanGoBack() const
593 return webkit_web_view_can_go_back(m_web_view
);
597 bool wxWebViewWebKit::CanGoForward() const
599 return webkit_web_view_can_go_forward(m_web_view
);
602 void wxWebViewWebKit::ClearHistory()
604 WebKitWebBackForwardList
* history
;
605 history
= webkit_web_view_get_back_forward_list(m_web_view
);
606 webkit_web_back_forward_list_clear(history
);
609 void wxWebViewWebKit::EnableHistory(bool enable
)
611 WebKitWebBackForwardList
* history
;
612 history
= webkit_web_view_get_back_forward_list(m_web_view
);
615 webkit_web_back_forward_list_set_limit(history
, m_historyLimit
);
619 webkit_web_back_forward_list_set_limit(history
, 0);
623 wxVector
<wxSharedPtr
<wxWebViewHistoryItem
> > wxWebViewWebKit::GetBackwardHistory()
625 wxVector
<wxSharedPtr
<wxWebViewHistoryItem
> > backhist
;
626 WebKitWebBackForwardList
* history
;
627 history
= webkit_web_view_get_back_forward_list(m_web_view
);
628 GList
* list
= webkit_web_back_forward_list_get_back_list_with_limit(history
,
630 //We need to iterate in reverse to get the order we desire
631 for(int i
= g_list_length(list
) - 1; i
>= 0 ; i
--)
633 WebKitWebHistoryItem
* gtkitem
= (WebKitWebHistoryItem
*)g_list_nth_data(list
, i
);
634 wxWebViewHistoryItem
* wxitem
= new wxWebViewHistoryItem(
635 webkit_web_history_item_get_uri(gtkitem
),
636 webkit_web_history_item_get_title(gtkitem
));
637 wxitem
->m_histItem
= gtkitem
;
638 wxSharedPtr
<wxWebViewHistoryItem
> item(wxitem
);
639 backhist
.push_back(item
);
644 wxVector
<wxSharedPtr
<wxWebViewHistoryItem
> > wxWebViewWebKit::GetForwardHistory()
646 wxVector
<wxSharedPtr
<wxWebViewHistoryItem
> > forwardhist
;
647 WebKitWebBackForwardList
* history
;
648 history
= webkit_web_view_get_back_forward_list(m_web_view
);
649 GList
* list
= webkit_web_back_forward_list_get_forward_list_with_limit(history
,
651 for(guint i
= 0; i
< g_list_length(list
); i
++)
653 WebKitWebHistoryItem
* gtkitem
= (WebKitWebHistoryItem
*)g_list_nth_data(list
, i
);
654 wxWebViewHistoryItem
* wxitem
= new wxWebViewHistoryItem(
655 webkit_web_history_item_get_uri(gtkitem
),
656 webkit_web_history_item_get_title(gtkitem
));
657 wxitem
->m_histItem
= gtkitem
;
658 wxSharedPtr
<wxWebViewHistoryItem
> item(wxitem
);
659 forwardhist
.push_back(item
);
664 void wxWebViewWebKit::LoadHistoryItem(wxSharedPtr
<wxWebViewHistoryItem
> item
)
666 WebKitWebHistoryItem
* gtkitem
= (WebKitWebHistoryItem
*)item
->m_histItem
;
669 webkit_web_view_go_to_back_forward_item(m_web_view
,
670 WEBKIT_WEB_HISTORY_ITEM(gtkitem
));
674 bool wxWebViewWebKit::CanCut() const
676 return webkit_web_view_can_cut_clipboard(m_web_view
);
679 bool wxWebViewWebKit::CanCopy() const
681 return webkit_web_view_can_copy_clipboard(m_web_view
);
684 bool wxWebViewWebKit::CanPaste() const
686 return webkit_web_view_can_paste_clipboard(m_web_view
);
689 void wxWebViewWebKit::Cut()
691 webkit_web_view_cut_clipboard(m_web_view
);
694 void wxWebViewWebKit::Copy()
696 webkit_web_view_copy_clipboard(m_web_view
);
699 void wxWebViewWebKit::Paste()
701 webkit_web_view_paste_clipboard(m_web_view
);
704 bool wxWebViewWebKit::CanUndo() const
706 return webkit_web_view_can_undo(m_web_view
);
709 bool wxWebViewWebKit::CanRedo() const
711 return webkit_web_view_can_redo(m_web_view
);
714 void wxWebViewWebKit::Undo()
716 webkit_web_view_undo(m_web_view
);
719 void wxWebViewWebKit::Redo()
721 webkit_web_view_redo(m_web_view
);
724 wxString
wxWebViewWebKit::GetCurrentURL() const
726 // FIXME: check which encoding the web kit control uses instead of
727 // assuming UTF8 (here and elsewhere too)
728 return wxString::FromUTF8(webkit_web_view_get_uri(m_web_view
));
732 wxString
wxWebViewWebKit::GetCurrentTitle() const
734 return wxString::FromUTF8(webkit_web_view_get_title(m_web_view
));
738 wxString
wxWebViewWebKit::GetPageSource() const
740 WebKitWebFrame
* frame
= webkit_web_view_get_main_frame(m_web_view
);
741 WebKitWebDataSource
* src
= webkit_web_frame_get_data_source (frame
);
743 // TODO: check encoding with
745 // webkit_web_data_source_get_encoding(WebKitWebDataSource *data_source);
746 return wxString(webkit_web_data_source_get_data (src
)->str
, wxConvUTF8
);
750 wxWebViewZoom
wxWebViewWebKit::GetZoom() const
752 float zoom
= GetWebkitZoom();
754 // arbitrary way to map float zoom to our common zoom enum
757 return wxWEBVIEW_ZOOM_TINY
;
759 else if (zoom
> 0.65 && zoom
<= 0.90)
761 return wxWEBVIEW_ZOOM_SMALL
;
763 else if (zoom
> 0.90 && zoom
<= 1.15)
765 return wxWEBVIEW_ZOOM_MEDIUM
;
767 else if (zoom
> 1.15 && zoom
<= 1.45)
769 return wxWEBVIEW_ZOOM_LARGE
;
771 else if (zoom
> 1.45)
773 return wxWEBVIEW_ZOOM_LARGEST
;
776 // to shut up compilers, this can never be reached logically
778 return wxWEBVIEW_ZOOM_MEDIUM
;
782 void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom
)
784 // arbitrary way to map our common zoom enum to float zoom
787 case wxWEBVIEW_ZOOM_TINY
:
791 case wxWEBVIEW_ZOOM_SMALL
:
795 case wxWEBVIEW_ZOOM_MEDIUM
:
799 case wxWEBVIEW_ZOOM_LARGE
:
803 case wxWEBVIEW_ZOOM_LARGEST
:
812 void wxWebViewWebKit::SetZoomType(wxWebViewZoomType type
)
814 webkit_web_view_set_full_content_zoom(m_web_view
,
815 (type
== wxWEBVIEW_ZOOM_TYPE_LAYOUT
?
819 wxWebViewZoomType
wxWebViewWebKit::GetZoomType() const
821 gboolean fczoom
= webkit_web_view_get_full_content_zoom(m_web_view
);
823 if (fczoom
) return wxWEBVIEW_ZOOM_TYPE_LAYOUT
;
824 else return wxWEBVIEW_ZOOM_TYPE_TEXT
;
827 bool wxWebViewWebKit::CanSetZoomType(wxWebViewZoomType
) const
829 // this port supports all zoom types
833 void wxWebViewWebKit::DoSetPage(const wxString
& html
, const wxString
& baseUri
)
835 webkit_web_view_load_string (m_web_view
,
836 html
.mb_str(wxConvUTF8
),
839 baseUri
.mb_str(wxConvUTF8
));
842 void wxWebViewWebKit::Print()
844 WebKitWebFrame
* frame
= webkit_web_view_get_main_frame(m_web_view
);
845 webkit_web_frame_print (frame
);
847 // GtkPrintOperationResult webkit_web_frame_print_full
848 // (WebKitWebFrame *frame,
849 // GtkPrintOperation *operation,
850 // GtkPrintOperationAction action,
856 bool wxWebViewWebKit::IsBusy() const
860 // This code looks nice but returns true after a page was cancelled
862 WebKitLoadStatus status = webkit_web_view_get_load_status
863 (WEBKIT_WEB_VIEW(web_view));
866 #if WEBKIT_CHECK_VERSION(1,1,16)
867 // WEBKIT_LOAD_FAILED is new in webkit 1.1.16
868 if (status == WEBKIT_LOAD_FAILED)
873 if (status == WEBKIT_LOAD_FINISHED)
882 void wxWebViewWebKit::SetEditable(bool enable
)
884 webkit_web_view_set_editable(m_web_view
, enable
);
887 bool wxWebViewWebKit::IsEditable() const
889 return webkit_web_view_get_editable(m_web_view
);
892 void wxWebViewWebKit::DeleteSelection()
894 webkit_web_view_delete_selection(m_web_view
);
897 bool wxWebViewWebKit::HasSelection() const
899 return webkit_web_view_has_selection(m_web_view
);
902 void wxWebViewWebKit::SelectAll()
904 webkit_web_view_select_all(m_web_view
);
907 wxString
wxWebViewWebKit::GetSelectedText() const
909 WebKitDOMDocument
* doc
;
910 WebKitDOMDOMWindow
* win
;
911 WebKitDOMDOMSelection
* sel
;
912 WebKitDOMRange
* range
;
914 doc
= webkit_web_view_get_dom_document(m_web_view
);
915 win
= webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc
));
916 sel
= webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win
));
917 range
= webkit_dom_dom_selection_get_range_at(WEBKIT_DOM_DOM_SELECTION(sel
),
919 return wxString(webkit_dom_range_get_text(WEBKIT_DOM_RANGE(range
)),
923 wxString
wxWebViewWebKit::GetSelectedSource() const
925 WebKitDOMDocument
* doc
;
926 WebKitDOMDOMWindow
* win
;
927 WebKitDOMDOMSelection
* sel
;
928 WebKitDOMRange
* range
;
929 WebKitDOMElement
* div
;
930 WebKitDOMDocumentFragment
* clone
;
931 WebKitDOMHTMLElement
* html
;
933 doc
= webkit_web_view_get_dom_document(m_web_view
);
934 win
= webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc
));
935 sel
= webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win
));
936 range
= webkit_dom_dom_selection_get_range_at(WEBKIT_DOM_DOM_SELECTION(sel
),
938 div
= webkit_dom_document_create_element(WEBKIT_DOM_DOCUMENT(doc
), "div", NULL
);
940 clone
= webkit_dom_range_clone_contents(WEBKIT_DOM_RANGE(range
), NULL
);
941 webkit_dom_node_append_child(&div
->parent_instance
, &clone
->parent_instance
, NULL
);
942 html
= (WebKitDOMHTMLElement
*)div
;
944 return wxString(webkit_dom_html_element_get_inner_html(WEBKIT_DOM_HTML_ELEMENT(html
)),
948 void wxWebViewWebKit::ClearSelection()
950 WebKitDOMDocument
* doc
;
951 WebKitDOMDOMWindow
* win
;
952 WebKitDOMDOMSelection
* sel
;
954 doc
= webkit_web_view_get_dom_document(m_web_view
);
955 win
= webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc
));
956 sel
= webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win
));
957 webkit_dom_dom_selection_remove_all_ranges(WEBKIT_DOM_DOM_SELECTION(sel
));
961 wxString
wxWebViewWebKit::GetPageText() const
963 WebKitDOMDocument
* doc
;
964 WebKitDOMHTMLElement
* body
;
966 doc
= webkit_web_view_get_dom_document(m_web_view
);
967 body
= webkit_dom_document_get_body(WEBKIT_DOM_DOCUMENT(doc
));
968 return wxString(webkit_dom_html_element_get_inner_text(WEBKIT_DOM_HTML_ELEMENT(body
)),
972 void wxWebViewWebKit::RunScript(const wxString
& javascript
)
974 webkit_web_view_execute_script(m_web_view
,
975 javascript
.mb_str(wxConvUTF8
));
978 void wxWebViewWebKit::RegisterHandler(wxSharedPtr
<wxWebViewHandler
> handler
)
980 m_handlerList
.push_back(handler
);
983 void wxWebViewWebKit::EnableContextMenu(bool enable
)
985 #if !WEBKIT_CHECK_VERSION(1, 10, 0) //If we are using an older version
986 g_object_set(webkit_web_view_get_settings(m_web_view
),
987 "enable-default-context-menu", enable
, NULL
);
989 wxWebView::EnableContextMenu(enable
);
992 long wxWebViewWebKit::Find(const wxString
& text
, int flags
)
994 bool newSearch
= false;
995 if(text
!= m_findText
||
996 (flags
& wxWEBVIEW_FIND_MATCH_CASE
) != (m_findFlags
& wxWEBVIEW_FIND_MATCH_CASE
))
999 //If it is a new search we need to clear existing highlights
1000 webkit_web_view_unmark_text_matches(m_web_view
);
1001 webkit_web_view_set_highlight_text_matches(m_web_view
, false);
1004 m_findFlags
= flags
;
1007 //If the search string is empty then we clear any selection and highlight
1010 webkit_web_view_unmark_text_matches(m_web_view
);
1011 webkit_web_view_set_highlight_text_matches(m_web_view
, false);
1016 bool wrap
= false, matchCase
= false, forward
= true;
1017 if(flags
& wxWEBVIEW_FIND_WRAP
)
1019 if(flags
& wxWEBVIEW_FIND_MATCH_CASE
)
1021 if(flags
& wxWEBVIEW_FIND_BACKWARDS
)
1026 //Initially we mark the matches to know how many we have
1027 m_findCount
= webkit_web_view_mark_text_matches(m_web_view
, wxGTK_CONV(text
), matchCase
, 0);
1028 //In this case we return early to match IE behaviour
1029 m_findPosition
= -1;
1038 if(m_findPosition
< 0)
1039 m_findPosition
+= m_findCount
;
1040 if(m_findPosition
> m_findCount
)
1041 m_findPosition
-= m_findCount
;
1044 //Highlight them if needed
1045 bool highlight
= flags
& wxWEBVIEW_FIND_HIGHLIGHT_RESULT
? true : false;
1046 webkit_web_view_set_highlight_text_matches(m_web_view
, highlight
);
1048 if(!webkit_web_view_search_text(m_web_view
, wxGTK_CONV(text
), matchCase
, forward
, wrap
))
1050 m_findPosition
= -1;
1054 wxLogMessage(wxString::Format("Returning %d", m_findPosition
));
1055 return newSearch
? m_findCount
: m_findPosition
;
1058 void wxWebViewWebKit::FindClear()
1063 m_findPosition
= -1;
1068 wxWebViewWebKit::GetClassDefaultAttributes(wxWindowVariant
WXUNUSED(variant
))
1070 return GetDefaultAttributesFromGTKWidget(webkit_web_view_new());
1074 #endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT