1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/webview_webkit.cpp
3 // Purpose: GTK WebKit backend for web view component
4 // Author: Marianne Gagnon, Robert Roebling
6 // Copyright: (c) 2010 Marianne Gagnon, 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
13 #if wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT
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"
22 #include <webkit/webkit.h>
24 // ----------------------------------------------------------------------------
26 // ----------------------------------------------------------------------------
32 wxgtk_webview_webkit_load_status(GtkWidget
* widget
,
34 wxWebViewWebKit
*webKitCtrl
)
36 // We can be called from webkit_web_view_dispose() during the window
37 // destruction, don't use half-destroyed object in this case.
38 if ( webKitCtrl
->IsBeingDeleted() )
41 wxString url
= webKitCtrl
->GetCurrentURL();
43 WebKitLoadStatus status
;
44 g_object_get(G_OBJECT(widget
), "load-status", &status
, NULL
);
46 wxString target
; // TODO: get target (if possible)
48 if (status
== WEBKIT_LOAD_FINISHED
)
50 WebKitWebBackForwardList
* hist
= webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(widget
));
51 WebKitWebHistoryItem
* item
= webkit_web_back_forward_list_get_current_item(hist
);
52 //We have to check if we are actually storing history
53 //If the item isn't added we add it ourselves, it isn't added otherwise
54 //with a custom scheme.
55 if(WEBKIT_IS_WEB_HISTORY_ITEM(item
) && webkit_web_history_item_get_uri(item
) != url
)
58 newitem
= webkit_web_history_item_new_with_data
61 webKitCtrl
->GetCurrentTitle().utf8_str()
63 webkit_web_back_forward_list_add_item(hist
, newitem
);
66 webKitCtrl
->m_busy
= false;
67 wxWebViewEvent
event(wxEVT_COMMAND_WEB_VIEW_LOADED
,
71 if (webKitCtrl
&& webKitCtrl
->GetEventHandler())
72 webKitCtrl
->GetEventHandler()->ProcessEvent(event
);
74 else if (status
== WEBKIT_LOAD_COMMITTED
)
76 webKitCtrl
->m_busy
= true;
77 wxWebViewEvent
event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED
,
81 if (webKitCtrl
&& webKitCtrl
->GetEventHandler())
82 webKitCtrl
->GetEventHandler()->ProcessEvent(event
);
87 wxgtk_webview_webkit_navigation(WebKitWebView
*,
88 WebKitWebFrame
*frame
,
89 WebKitNetworkRequest
*request
,
90 WebKitWebNavigationAction
*,
91 WebKitWebPolicyDecision
*policy_decision
,
92 wxWebViewWebKit
*webKitCtrl
)
94 if(webKitCtrl
->m_guard
)
96 webKitCtrl
->m_guard
= false;
97 //We set this to make sure that we don't try to load the page again from
98 //the resource request callback
99 webKitCtrl
->m_vfsurl
= webkit_network_request_get_uri(request
);
100 webkit_web_policy_decision_use(policy_decision
);
104 webKitCtrl
->m_busy
= true;
106 const gchar
* uri
= webkit_network_request_get_uri(request
);
108 wxString target
= webkit_web_frame_get_name (frame
);
109 wxWebViewEvent
event(wxEVT_COMMAND_WEB_VIEW_NAVIGATING
,
111 wxString( uri
, wxConvUTF8
),
114 if (webKitCtrl
&& webKitCtrl
->GetEventHandler())
115 webKitCtrl
->GetEventHandler()->ProcessEvent(event
);
117 if (!event
.IsAllowed())
119 webKitCtrl
->m_busy
= false;
120 webkit_web_policy_decision_ignore(policy_decision
);
125 wxString wxuri
= uri
;
126 wxSharedPtr
<wxWebViewHandler
> handler
;
127 wxVector
<wxSharedPtr
<wxWebViewHandler
> > hanlders
= webKitCtrl
->GetHandlers();
128 //We are not vetoed so see if we match one of the additional handlers
129 for(wxVector
<wxSharedPtr
<wxWebViewHandler
> >::iterator it
= hanlders
.begin();
130 it
!= hanlders
.end(); ++it
)
132 if(wxuri
.substr(0, (*it
)->GetName().length()) == (*it
)->GetName())
137 //If we found a handler we can then use it to load the file directly
141 webKitCtrl
->m_guard
= true;
142 wxFSFile
* file
= handler
->GetFile(wxuri
);
145 webKitCtrl
->SetPage(*file
->GetStream(), wxuri
);
147 //We need to throw some sort of error here if file is NULL
148 webkit_web_policy_decision_ignore(policy_decision
);
156 wxgtk_webview_webkit_error(WebKitWebView
*,
160 wxWebViewWebKit
* webKitWindow
)
162 webKitWindow
->m_busy
= false;
163 wxWebViewNavigationError type
= wxWEB_NAV_ERR_OTHER
;
165 GError
* error
= (GError
*)web_error
;
166 wxString
description(error
->message
, wxConvUTF8
);
168 if (strcmp(g_quark_to_string(error
->domain
), "soup_http_error_quark") == 0)
172 case SOUP_STATUS_CANCELLED
:
173 type
= wxWEB_NAV_ERR_USER_CANCELLED
;
176 case SOUP_STATUS_CANT_RESOLVE
:
177 case SOUP_STATUS_NOT_FOUND
:
178 type
= wxWEB_NAV_ERR_NOT_FOUND
;
181 case SOUP_STATUS_CANT_RESOLVE_PROXY
:
182 case SOUP_STATUS_CANT_CONNECT
:
183 case SOUP_STATUS_CANT_CONNECT_PROXY
:
184 case SOUP_STATUS_SSL_FAILED
:
185 case SOUP_STATUS_IO_ERROR
:
186 type
= wxWEB_NAV_ERR_CONNECTION
;
189 case SOUP_STATUS_MALFORMED
:
190 //case SOUP_STATUS_TOO_MANY_REDIRECTS:
191 type
= wxWEB_NAV_ERR_REQUEST
;
194 //case SOUP_STATUS_NO_CONTENT:
195 //case SOUP_STATUS_RESET_CONTENT:
197 case SOUP_STATUS_BAD_REQUEST
:
198 type
= wxWEB_NAV_ERR_REQUEST
;
201 case SOUP_STATUS_UNAUTHORIZED
:
202 case SOUP_STATUS_FORBIDDEN
:
203 type
= wxWEB_NAV_ERR_AUTH
;
206 case SOUP_STATUS_METHOD_NOT_ALLOWED
:
207 case SOUP_STATUS_NOT_ACCEPTABLE
:
208 type
= wxWEB_NAV_ERR_SECURITY
;
211 case SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED
:
212 type
= wxWEB_NAV_ERR_AUTH
;
215 case SOUP_STATUS_REQUEST_TIMEOUT
:
216 type
= wxWEB_NAV_ERR_CONNECTION
;
219 //case SOUP_STATUS_PAYMENT_REQUIRED:
220 case SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE
:
221 case SOUP_STATUS_REQUEST_URI_TOO_LONG
:
222 case SOUP_STATUS_UNSUPPORTED_MEDIA_TYPE
:
223 type
= wxWEB_NAV_ERR_REQUEST
;
226 case SOUP_STATUS_BAD_GATEWAY
:
227 case SOUP_STATUS_SERVICE_UNAVAILABLE
:
228 case SOUP_STATUS_GATEWAY_TIMEOUT
:
229 type
= wxWEB_NAV_ERR_CONNECTION
;
232 case SOUP_STATUS_HTTP_VERSION_NOT_SUPPORTED
:
233 type
= wxWEB_NAV_ERR_REQUEST
;
235 //case SOUP_STATUS_INSUFFICIENT_STORAGE:
236 //case SOUP_STATUS_NOT_EXTENDED:
239 else if (strcmp(g_quark_to_string(error
->domain
),
240 "webkit-network-error-quark") == 0)
244 //WEBKIT_NETWORK_ERROR_FAILED:
245 //WEBKIT_NETWORK_ERROR_TRANSPORT:
247 case WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL
:
248 type
= wxWEB_NAV_ERR_REQUEST
;
251 case WEBKIT_NETWORK_ERROR_CANCELLED
:
252 type
= wxWEB_NAV_ERR_USER_CANCELLED
;
255 case WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST
:
256 type
= wxWEB_NAV_ERR_NOT_FOUND
;
260 else if (strcmp(g_quark_to_string(error
->domain
),
261 "webkit-policy-error-quark") == 0)
265 //case WEBKIT_POLICY_ERROR_FAILED:
266 //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE:
267 //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_URL:
268 //case WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE:
269 case WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT
:
270 type
= wxWEB_NAV_ERR_SECURITY
;
275 webkit_plugin_error_quark
278 printf("Error domain %s\n", g_quark_to_string(error->domain));
282 wxWebViewEvent
event(wxEVT_COMMAND_WEB_VIEW_ERROR
,
283 webKitWindow
->GetId(),
285 event
.SetString(description
);
288 if (webKitWindow
&& webKitWindow
->GetEventHandler())
290 webKitWindow
->GetEventHandler()->ProcessEvent(event
);
297 wxgtk_webview_webkit_new_window(WebKitWebView
*,
298 WebKitWebFrame
*frame
,
299 WebKitNetworkRequest
*request
,
300 WebKitWebNavigationAction
*,
301 WebKitWebPolicyDecision
*policy_decision
,
302 wxWebViewWebKit
*webKitCtrl
)
304 const gchar
* uri
= webkit_network_request_get_uri(request
);
306 wxString target
= webkit_web_frame_get_name (frame
);
307 wxWebViewEvent
event(wxEVT_COMMAND_WEB_VIEW_NEWWINDOW
,
309 wxString( uri
, wxConvUTF8
),
312 if (webKitCtrl
&& webKitCtrl
->GetEventHandler())
313 webKitCtrl
->GetEventHandler()->ProcessEvent(event
);
315 //We always want the user to handle this themselves
316 webkit_web_policy_decision_ignore(policy_decision
);
321 wxgtk_webview_webkit_title_changed(WebKitWebView
*,
324 wxWebViewWebKit
*webKitCtrl
)
326 wxWebViewEvent
event(wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED
,
328 webKitCtrl
->GetCurrentURL(),
330 event
.SetString(wxString(title
, wxConvUTF8
));
332 if (webKitCtrl
&& webKitCtrl
->GetEventHandler())
333 webKitCtrl
->GetEventHandler()->ProcessEvent(event
);
338 wxgtk_webview_webkit_resource_req(WebKitWebView
*,
341 WebKitNetworkRequest
*request
,
342 WebKitNetworkResponse
*,
343 wxWebViewWebKit
*webKitCtrl
)
345 wxString uri
= webkit_network_request_get_uri(request
);
347 wxSharedPtr
<wxWebViewHandler
> handler
;
348 wxVector
<wxSharedPtr
<wxWebViewHandler
> > hanlders
= webKitCtrl
->GetHandlers();
350 //We are not vetoed so see if we match one of the additional handlers
351 for(wxVector
<wxSharedPtr
<wxWebViewHandler
> >::iterator it
= hanlders
.begin();
352 it
!= hanlders
.end(); ++it
)
354 if(uri
.substr(0, (*it
)->GetName().length()) == (*it
)->GetName())
359 //If we found a handler we can then use it to load the file directly
363 //If it is requsting the page itself then return as we have already
364 //loaded it from the archive
365 if(webKitCtrl
->m_vfsurl
== uri
)
368 wxFSFile
* file
= handler
->GetFile(uri
);
371 //We load the data into a data url to save it being written out again
372 size_t size
= file
->GetStream()->GetLength();
373 char *buffer
= new char[size
];
374 file
->GetStream()->Read(buffer
, size
);
375 wxString data
= wxBase64Encode(buffer
, size
);
377 wxString mime
= file
->GetMimeType();
378 wxString path
= "data:" + mime
+ ";base64," + data
;
379 //Then we can redirect the call
380 webkit_network_request_set_uri(request
, path
.utf8_str());
388 //-----------------------------------------------------------------------------
390 //-----------------------------------------------------------------------------
392 wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewWebKit
, wxWebView
);
394 bool wxWebViewWebKit::Create(wxWindow
*parent
,
400 const wxString
& name
)
406 // We currently unconditionally impose scrolling in both directions as it's
407 // necessary to show arbitrary pages.
408 style
|= wxHSCROLL
| wxVSCROLL
;
410 if (!PreCreation( parent
, pos
, size
) ||
411 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
413 wxFAIL_MSG( wxT("wxWebViewWebKit creation failed") );
417 m_web_view
= WEBKIT_WEB_VIEW(webkit_web_view_new());
418 GTKCreateScrolledWindowWith(GTK_WIDGET(m_web_view
));
419 g_object_ref(m_widget
);
421 g_signal_connect_after(m_web_view
, "navigation-policy-decision-requested",
422 G_CALLBACK(wxgtk_webview_webkit_navigation
),
424 g_signal_connect_after(m_web_view
, "load-error",
425 G_CALLBACK(wxgtk_webview_webkit_error
),
428 g_signal_connect_after(m_web_view
, "new-window-policy-decision-requested",
429 G_CALLBACK(wxgtk_webview_webkit_new_window
), this);
431 g_signal_connect_after(m_web_view
, "title-changed",
432 G_CALLBACK(wxgtk_webview_webkit_title_changed
), this);
434 g_signal_connect_after(m_web_view
, "resource-request-starting",
435 G_CALLBACK(wxgtk_webview_webkit_resource_req
), this);
437 m_parent
->DoAddChild( this );
442 webkit_web_view_load_uri(m_web_view
, url
.utf8_str());
444 //Get the initial history limit so we can enable and disable it later
445 WebKitWebBackForwardList
* history
;
446 history
= webkit_web_view_get_back_forward_list(m_web_view
);
447 m_historyLimit
= webkit_web_back_forward_list_get_limit(history
);
449 // last to avoid getting signal too early
450 g_signal_connect_after(m_web_view
, "notify::load-status",
451 G_CALLBACK(wxgtk_webview_webkit_load_status
),
457 wxWebViewWebKit::~wxWebViewWebKit()
459 // The main goal here is to set m_isBeingDeleted to true to avoid the use
460 // of this -- already half-destroyed -- object from WebKit callbacks, but
461 // just setting it would prevent wxWindowDestroyEvent from being sent, so
462 // send it now instead.
466 bool wxWebViewWebKit::Enable( bool enable
)
468 if (!wxControl::Enable(enable
))
471 gtk_widget_set_sensitive(gtk_bin_get_child(GTK_BIN(m_widget
)), enable
);
474 // GTKFixSensitivity();
480 wxWebViewWebKit::GTKGetWindow(wxArrayGdkWindows
& WXUNUSED(windows
)) const
482 GdkWindow
* window
= gtk_widget_get_parent_window(m_widget
);
486 void wxWebViewWebKit::ZoomIn()
488 webkit_web_view_zoom_in(m_web_view
);
491 void wxWebViewWebKit::ZoomOut()
493 webkit_web_view_zoom_out(m_web_view
);
496 void wxWebViewWebKit::SetWebkitZoom(float level
)
498 webkit_web_view_set_zoom_level(m_web_view
, level
);
501 float wxWebViewWebKit::GetWebkitZoom() const
503 return webkit_web_view_get_zoom_level(m_web_view
);
506 void wxWebViewWebKit::Stop()
508 webkit_web_view_stop_loading(m_web_view
);
511 void wxWebViewWebKit::Reload(wxWebViewReloadFlags flags
)
513 if (flags
& wxWEB_VIEW_RELOAD_NO_CACHE
)
515 webkit_web_view_reload_bypass_cache(m_web_view
);
519 webkit_web_view_reload(m_web_view
);
523 void wxWebViewWebKit::LoadURL(const wxString
& url
)
525 webkit_web_view_load_uri(m_web_view
, wxGTK_CONV(url
));
529 void wxWebViewWebKit::GoBack()
531 webkit_web_view_go_back(m_web_view
);
534 void wxWebViewWebKit::GoForward()
536 webkit_web_view_go_forward(m_web_view
);
540 bool wxWebViewWebKit::CanGoBack() const
542 return webkit_web_view_can_go_back(m_web_view
);
546 bool wxWebViewWebKit::CanGoForward() const
548 return webkit_web_view_can_go_forward(m_web_view
);
551 void wxWebViewWebKit::ClearHistory()
553 WebKitWebBackForwardList
* history
;
554 history
= webkit_web_view_get_back_forward_list(m_web_view
);
555 webkit_web_back_forward_list_clear(history
);
558 void wxWebViewWebKit::EnableHistory(bool enable
)
560 WebKitWebBackForwardList
* history
;
561 history
= webkit_web_view_get_back_forward_list(m_web_view
);
564 webkit_web_back_forward_list_set_limit(history
, m_historyLimit
);
568 webkit_web_back_forward_list_set_limit(history
, 0);
572 wxVector
<wxSharedPtr
<wxWebViewHistoryItem
> > wxWebViewWebKit::GetBackwardHistory()
574 wxVector
<wxSharedPtr
<wxWebViewHistoryItem
> > backhist
;
575 WebKitWebBackForwardList
* history
;
576 history
= webkit_web_view_get_back_forward_list(m_web_view
);
577 GList
* list
= webkit_web_back_forward_list_get_back_list_with_limit(history
,
579 //We need to iterate in reverse to get the order we desire
580 for(int i
= g_list_length(list
) - 1; i
>= 0 ; i
--)
582 WebKitWebHistoryItem
* gtkitem
= (WebKitWebHistoryItem
*)g_list_nth_data(list
, i
);
583 wxWebViewHistoryItem
* wxitem
= new wxWebViewHistoryItem(
584 webkit_web_history_item_get_uri(gtkitem
),
585 webkit_web_history_item_get_title(gtkitem
));
586 wxitem
->m_histItem
= gtkitem
;
587 wxSharedPtr
<wxWebViewHistoryItem
> item(wxitem
);
588 backhist
.push_back(item
);
593 wxVector
<wxSharedPtr
<wxWebViewHistoryItem
> > wxWebViewWebKit::GetForwardHistory()
595 wxVector
<wxSharedPtr
<wxWebViewHistoryItem
> > forwardhist
;
596 WebKitWebBackForwardList
* history
;
597 history
= webkit_web_view_get_back_forward_list(m_web_view
);
598 GList
* list
= webkit_web_back_forward_list_get_forward_list_with_limit(history
,
600 for(guint i
= 0; i
< g_list_length(list
); i
++)
602 WebKitWebHistoryItem
* gtkitem
= (WebKitWebHistoryItem
*)g_list_nth_data(list
, i
);
603 wxWebViewHistoryItem
* wxitem
= new wxWebViewHistoryItem(
604 webkit_web_history_item_get_uri(gtkitem
),
605 webkit_web_history_item_get_title(gtkitem
));
606 wxitem
->m_histItem
= gtkitem
;
607 wxSharedPtr
<wxWebViewHistoryItem
> item(wxitem
);
608 forwardhist
.push_back(item
);
613 void wxWebViewWebKit::LoadHistoryItem(wxSharedPtr
<wxWebViewHistoryItem
> item
)
615 WebKitWebHistoryItem
* gtkitem
= (WebKitWebHistoryItem
*)item
->m_histItem
;
618 webkit_web_view_go_to_back_forward_item(m_web_view
,
619 WEBKIT_WEB_HISTORY_ITEM(gtkitem
));
623 bool wxWebViewWebKit::CanCut() const
625 return webkit_web_view_can_cut_clipboard(m_web_view
);
628 bool wxWebViewWebKit::CanCopy() const
630 return webkit_web_view_can_copy_clipboard(m_web_view
);
633 bool wxWebViewWebKit::CanPaste() const
635 return webkit_web_view_can_paste_clipboard(m_web_view
);
638 void wxWebViewWebKit::Cut()
640 webkit_web_view_cut_clipboard(m_web_view
);
643 void wxWebViewWebKit::Copy()
645 webkit_web_view_copy_clipboard(m_web_view
);
648 void wxWebViewWebKit::Paste()
650 webkit_web_view_paste_clipboard(m_web_view
);
653 bool wxWebViewWebKit::CanUndo() const
655 return webkit_web_view_can_undo(m_web_view
);
658 bool wxWebViewWebKit::CanRedo() const
660 return webkit_web_view_can_redo(m_web_view
);
663 void wxWebViewWebKit::Undo()
665 webkit_web_view_undo(m_web_view
);
668 void wxWebViewWebKit::Redo()
670 webkit_web_view_redo(m_web_view
);
673 wxString
wxWebViewWebKit::GetCurrentURL() const
675 // FIXME: check which encoding the web kit control uses instead of
676 // assuming UTF8 (here and elsewhere too)
677 return wxString::FromUTF8(webkit_web_view_get_uri(m_web_view
));
681 wxString
wxWebViewWebKit::GetCurrentTitle() const
683 return wxString::FromUTF8(webkit_web_view_get_title(m_web_view
));
687 wxString
wxWebViewWebKit::GetPageSource() const
689 WebKitWebFrame
* frame
= webkit_web_view_get_main_frame(m_web_view
);
690 WebKitWebDataSource
* src
= webkit_web_frame_get_data_source (frame
);
692 // TODO: check encoding with
694 // webkit_web_data_source_get_encoding(WebKitWebDataSource *data_source);
695 return wxString(webkit_web_data_source_get_data (src
)->str
, wxConvUTF8
);
699 wxWebViewZoom
wxWebViewWebKit::GetZoom() const
701 float zoom
= GetWebkitZoom();
703 // arbitrary way to map float zoom to our common zoom enum
706 return wxWEB_VIEW_ZOOM_TINY
;
708 else if (zoom
> 0.65 && zoom
<= 0.90)
710 return wxWEB_VIEW_ZOOM_SMALL
;
712 else if (zoom
> 0.90 && zoom
<= 1.15)
714 return wxWEB_VIEW_ZOOM_MEDIUM
;
716 else if (zoom
> 1.15 && zoom
<= 1.45)
718 return wxWEB_VIEW_ZOOM_LARGE
;
720 else if (zoom
> 1.45)
722 return wxWEB_VIEW_ZOOM_LARGEST
;
725 // to shut up compilers, this can never be reached logically
727 return wxWEB_VIEW_ZOOM_MEDIUM
;
731 void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom
)
733 // arbitrary way to map our common zoom enum to float zoom
736 case wxWEB_VIEW_ZOOM_TINY
:
740 case wxWEB_VIEW_ZOOM_SMALL
:
744 case wxWEB_VIEW_ZOOM_MEDIUM
:
748 case wxWEB_VIEW_ZOOM_LARGE
:
752 case wxWEB_VIEW_ZOOM_LARGEST
:
761 void wxWebViewWebKit::SetZoomType(wxWebViewZoomType type
)
763 webkit_web_view_set_full_content_zoom(m_web_view
,
764 (type
== wxWEB_VIEW_ZOOM_TYPE_LAYOUT
?
768 wxWebViewZoomType
wxWebViewWebKit::GetZoomType() const
770 gboolean fczoom
= webkit_web_view_get_full_content_zoom(m_web_view
);
772 if (fczoom
) return wxWEB_VIEW_ZOOM_TYPE_LAYOUT
;
773 else return wxWEB_VIEW_ZOOM_TYPE_TEXT
;
776 bool wxWebViewWebKit::CanSetZoomType(wxWebViewZoomType
) const
778 // this port supports all zoom types
782 void wxWebViewWebKit::DoSetPage(const wxString
& html
, const wxString
& baseUri
)
784 webkit_web_view_load_string (m_web_view
,
785 html
.mb_str(wxConvUTF8
),
788 baseUri
.mb_str(wxConvUTF8
));
791 void wxWebViewWebKit::Print()
793 WebKitWebFrame
* frame
= webkit_web_view_get_main_frame(m_web_view
);
794 webkit_web_frame_print (frame
);
796 // GtkPrintOperationResult webkit_web_frame_print_full
797 // (WebKitWebFrame *frame,
798 // GtkPrintOperation *operation,
799 // GtkPrintOperationAction action,
805 bool wxWebViewWebKit::IsBusy() const
809 // This code looks nice but returns true after a page was cancelled
811 WebKitLoadStatus status = webkit_web_view_get_load_status
812 (WEBKIT_WEB_VIEW(web_view));
815 #if WEBKIT_CHECK_VERSION(1,1,16)
816 // WEBKIT_LOAD_FAILED is new in webkit 1.1.16
817 if (status == WEBKIT_LOAD_FAILED)
822 if (status == WEBKIT_LOAD_FINISHED)
831 void wxWebViewWebKit::SetEditable(bool enable
)
833 webkit_web_view_set_editable(m_web_view
, enable
);
836 bool wxWebViewWebKit::IsEditable() const
838 return webkit_web_view_get_editable(m_web_view
);
841 void wxWebViewWebKit::DeleteSelection()
843 webkit_web_view_delete_selection(m_web_view
);
846 bool wxWebViewWebKit::HasSelection() const
848 return webkit_web_view_has_selection(m_web_view
);
851 void wxWebViewWebKit::SelectAll()
853 webkit_web_view_select_all(m_web_view
);
856 wxString
wxWebViewWebKit::GetSelectedText() const
858 WebKitDOMDocument
* doc
;
859 WebKitDOMDOMWindow
* win
;
860 WebKitDOMDOMSelection
* sel
;
861 WebKitDOMRange
* range
;
863 doc
= webkit_web_view_get_dom_document(m_web_view
);
864 win
= webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc
));
865 sel
= webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win
));
866 range
= webkit_dom_dom_selection_get_range_at(WEBKIT_DOM_DOM_SELECTION(sel
),
868 return wxString(webkit_dom_range_get_text(WEBKIT_DOM_RANGE(range
)),
872 wxString
wxWebViewWebKit::GetSelectedSource() const
874 WebKitDOMDocument
* doc
;
875 WebKitDOMDOMWindow
* win
;
876 WebKitDOMDOMSelection
* sel
;
877 WebKitDOMRange
* range
;
878 WebKitDOMElement
* div
;
879 WebKitDOMDocumentFragment
* clone
;
880 WebKitDOMHTMLElement
* html
;
882 doc
= webkit_web_view_get_dom_document(m_web_view
);
883 win
= webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc
));
884 sel
= webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win
));
885 range
= webkit_dom_dom_selection_get_range_at(WEBKIT_DOM_DOM_SELECTION(sel
),
887 div
= webkit_dom_document_create_element(WEBKIT_DOM_DOCUMENT(doc
), "div", NULL
);
889 clone
= webkit_dom_range_clone_contents(WEBKIT_DOM_RANGE(range
), NULL
);
890 webkit_dom_node_append_child(&div
->parent_instance
, &clone
->parent_instance
, NULL
);
891 html
= (WebKitDOMHTMLElement
*)div
;
893 return wxString(webkit_dom_html_element_get_inner_html(WEBKIT_DOM_HTML_ELEMENT(html
)),
897 void wxWebViewWebKit::ClearSelection()
899 WebKitDOMDocument
* doc
;
900 WebKitDOMDOMWindow
* win
;
901 WebKitDOMDOMSelection
* sel
;
903 doc
= webkit_web_view_get_dom_document(m_web_view
);
904 win
= webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc
));
905 sel
= webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win
));
906 webkit_dom_dom_selection_remove_all_ranges(WEBKIT_DOM_DOM_SELECTION(sel
));
910 wxString
wxWebViewWebKit::GetPageText() const
912 WebKitDOMDocument
* doc
;
913 WebKitDOMHTMLElement
* body
;
915 doc
= webkit_web_view_get_dom_document(m_web_view
);
916 body
= webkit_dom_document_get_body(WEBKIT_DOM_DOCUMENT(doc
));
917 return wxString(webkit_dom_html_element_get_inner_text(WEBKIT_DOM_HTML_ELEMENT(body
)),
921 void wxWebViewWebKit::RunScript(const wxString
& javascript
)
923 webkit_web_view_execute_script(m_web_view
,
924 javascript
.mb_str(wxConvUTF8
));
927 void wxWebViewWebKit::RegisterHandler(wxSharedPtr
<wxWebViewHandler
> handler
)
929 m_handlerList
.push_back(handler
);
932 long wxWebViewWebKit::Find(const wxString
& text
, int flags
)
934 bool newSearch
= false;
935 if(text
!= m_findText
||
936 (flags
& wxWEB_VIEW_FIND_MATCH_CASE
) != (m_findFlags
& wxWEB_VIEW_FIND_MATCH_CASE
))
939 //If it is a new search we need to clear existing highlights
940 webkit_web_view_unmark_text_matches(m_web_view
);
941 webkit_web_view_set_highlight_text_matches(m_web_view
, false);
947 //If the search string is empty then we clear any selection and highlight
950 webkit_web_view_unmark_text_matches(m_web_view
);
951 webkit_web_view_set_highlight_text_matches(m_web_view
, false);
956 bool wrap
= false, matchCase
= false, forward
= true;
957 if(flags
& wxWEB_VIEW_FIND_WRAP
)
959 if(flags
& wxWEB_VIEW_FIND_MATCH_CASE
)
961 if(flags
& wxWEB_VIEW_FIND_BACKWARDS
)
966 //Initially we mark the matches to know how many we have
967 m_findCount
= webkit_web_view_mark_text_matches(m_web_view
, wxGTK_CONV(text
), matchCase
, 0);
968 //In this case we return early to match IE behaviour
978 if(m_findPosition
< 0)
979 m_findPosition
+= m_findCount
;
980 if(m_findPosition
> m_findCount
)
981 m_findPosition
-= m_findCount
;
984 //Highlight them if needed
985 bool highlight
= flags
& wxWEB_VIEW_FIND_HIGHLIGHT_RESULT
? true : false;
986 webkit_web_view_set_highlight_text_matches(m_web_view
, highlight
);
988 if(!webkit_web_view_search_text(m_web_view
, wxGTK_CONV(text
), matchCase
, forward
, wrap
))
994 wxLogMessage(wxString::Format("Returning %d", m_findPosition
));
995 return newSearch
? m_findCount
: m_findPosition
;
998 void wxWebViewWebKit::FindClear()
1003 m_findPosition
= -1;
1008 wxWebViewWebKit::GetClassDefaultAttributes(wxWindowVariant
WXUNUSED(variant
))
1010 return GetDefaultAttributesFromGTKWidget(webkit_web_view_new
);
1014 #endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT